【问题标题】:in c#, how can i build up array from A to ZZ that is similar to the way that excel orders columns在 c# 中,我如何构建从 A 到 ZZ 的数组,类似于 excel 排序列的方式
【发布时间】:2011-03-21 22:34:51
【问题描述】:

我正在寻找可以生成数组的代码,其中第一项是 A,然后是 B,然后是 C。 . .在 Z 之后,它会转到 AA,然后是 AB,然后是 AC。 . .一直到 ZZ

在 C# 中执行此操作的最佳方法是什么?

【问题讨论】:

    标签: c# algorithm


    【解决方案1】:

    其中一种方法是:

    IEnumerable<string> generate()
    {
        for (char c = 'A'; c <= 'Z'; c++)
            yield return new string(c, 1);
        for (char c = 'A'; c <= 'Z'; c++)
            for (char d = 'A'; d <= 'Z'; d++)
                yield return new string(new[] { c, d });
    }
    

    编辑:
    您实际上可以使用更复杂的代码生成“无限”序列(以最大 long 值为界):

    string toBase26(long i)
    {
        if (i == 0) return ""; i--;
        return toBase26(i / 26) + (char)('A' + i % 26);
    }
    
    IEnumerable<string> generate()
    {
        long n = 0;
        while (true) yield return toBase26(++n);
    }
    

    这个是这样的:A,B,...,Z,AA,AB,...,ZZ,AAA,AAB,...等:

    foreach (var s in generate().Take(200)) Console.WriteLine(s);
    

    【讨论】:

    • 这太简单了,优雅得吓人:)
    • 第二种情况我会返回new string(new [] {c, d})
    • @Snowbear:是的,你的方式更优雅,我会改变它。
    • 这不是 Base 26,因为 AAA 不同。另请参阅stackoverflow.com/questions/763691/…,其中几个答案也给出了逆运算。
    • @Svante:是的,但非常接近。这个名字有点误导,我同意。 (逆运算也很简单。)
    【解决方案2】:

    弗拉德的好回答。

    这是另一个变化:

     static IEnumerable<string> generate() {
       for (char c = 'A'; c <= 'Z'; c++) {
         yield return c.ToString();
       }
    
       foreach (string s in generate()) {
         for (char c = 'A'; c <= 'Z'; c++) {
           yield return s + c;
         }
       }
     }
    

    如果你不介意以空字符串开始序列,你可以这样写:

     static IEnumerable<string> generate() {
       yield return "";
    
       foreach (string s in generate()) {
         for (char c = 'A'; c <= 'Z'; c++) {
           yield return s + c;
         }
       }
     }
    

    【讨论】:

    • 哇,很好的无限递归用法!我希望我发明了这个。如果只用yield return ""; 替换第一个循环,可能会更简单。
    【解决方案3】:

    您可以使用Enumerable.Range 生成数字并将它们转换为char 以生成A-Z。下一步是将它们结合起来。

    【讨论】:

      【解决方案4】:

      虽然在 PHP 中,但在 SO 中找到了这个。这会有帮助吗? Algorithm to get the excel-like column name of a number

      【讨论】:

        【解决方案5】:
        var q = Enumerable.Range(Convert.ToInt32('A'),26).Select( x => Convert.ToChar(x) );
        var result = (
          q.Select( x => x.ToString() )
           .Concat( 
              q.SelectMany(
                x => q.Select( y => x.ToString() + y.ToString() )
              )
           )
        );
        

        【讨论】:

        • Linq 应该用来让代码可读,而不是让代码 Linqish
        • 我认为作为他所要求的功能性表达非常好。 Vlad 看起来更好看,没错,但这只是因为编译器隐藏了它为使其工作而创建的所有杂物。
        【解决方案6】:

        这是一种方法。 :)

        string[] values =
          Enumerable.Range(0, 27 * 26)
          .Select(
            n => new String(
              new[] { (char)('@' + n / 26), (char)('A' + n % 26) },
              n < 26 ? 1 : 0, n < 26 ? 1 : 2
            )
          )
          .ToArray();
        

        【讨论】:

          【解决方案7】:
          class Program
          {
              public static string IntegerToExcelColumn(int col)
              {
                  // I've put a 256 upper bound here because Excel 2003 
                  // allows only 256 columns. Change it if you're using 
                  // Excel 2007 or 2010.
                  Debug.Assert(col >= 1 && col <= 256);
          
                  if (col >= 1 && col <= 26)
                  {
                      return ((char)(((int)'A') + (col - 1))).ToString();
                  }
          
                  // I've put a 256 upper bound here because Excel 2003 
                  // allows only 256 columns. Change it if you're using 
                  // Excel 2007 or 2010.
                  if (col > 26 && col <= 256)
                  {
                      int rem = col % 26;
                      int pri = col / 26;
                      if (rem == 0)
                      {
                          rem = 26;
                          pri--;
                      }
                      char[] buffer = new char[2];
                      buffer[0] = (char)(((int)'A') + (pri - 1));
                      buffer[1] = (char)(((int)'A') + (rem - 1));
                      return new string(buffer);
                  }
          
                  return "";
              }
          
              static void Main(string[] args)
              {
                  string[] columns= new string[255];
                  for (int i = 1; i <= 255; i++)
                      columns[i-1] = IntegerToExcelColumn(i);
                  foreach(var col in columns)
                      Console.WriteLine(col);
              }
          }
          

          【讨论】:

            【解决方案8】:

            查看ASCII table 并记下字符的值。您应该能够计算出一个循环,将字符从 A 增加到 Z 的次数与复制字符所需的次数一样多。 :)

            【讨论】:

              【解决方案9】:

              你也可以试试这个。 A到ZZ

              public class Program
              {
                  public static void Main()
                  {
                      int c=1;
                      string cc=AtoZZ(c);
                      for(int i=1;i<=702;i++){
                      cc=AtoZZ(i);
                      Console.WriteLine(cc);
                      }
                  }
              
                  static string AtoZZ(int chr)
                  {
                      char c1;
                      char c2;
                      string alp = "";
                      if(chr<=26)
                      {
                          c1 = (char)(chr + 64);
                          alp = c1 + "";
                      }        
                      else
                      {
                          int cl1 = chr / 26;
                          int cl2 = chr % 26;
                          if(cl2==0){
                              cl1--;
                              cl2=26;
                          }
                          c1 = (char)(cl1 + 64);
                          c2 = (char)(cl2 + 64);
                          alp = c1 + "" + c2;
                      }
                      return alp;
                   }
              }
              

              【讨论】:

                【解决方案10】:

                为了补充弗拉德的回答,这里是 ToBase26(int) 的反向操作:

                static long ToBase10(string str)
                {
                   if (string.IsNullOrWhiteSpace(str)) return 0;
                   var value = str[0] - 'A' + 1;
                
                   return (long) (value * Math.Pow(26, str.Length - 1) + 
                          ToBase10(str.Substring(1, str.Length - 1)));
                }
                

                【讨论】:

                  猜你喜欢
                  • 2022-06-15
                  • 2022-01-13
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多