【发布时间】:2011-03-21 22:34:51
【问题描述】:
我正在寻找可以生成数组的代码,其中第一项是 A,然后是 B,然后是 C。 . .在 Z 之后,它会转到 AA,然后是 AB,然后是 AC。 . .一直到 ZZ。
在 C# 中执行此操作的最佳方法是什么?
【问题讨论】:
我正在寻找可以生成数组的代码,其中第一项是 A,然后是 B,然后是 C。 . .在 Z 之后,它会转到 AA,然后是 AB,然后是 AC。 . .一直到 ZZ。
在 C# 中执行此操作的最佳方法是什么?
【问题讨论】:
其中一种方法是:
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})
AA 与 A 不同。另请参阅stackoverflow.com/questions/763691/…,其中几个答案也给出了逆运算。
弗拉德的好回答。
这是另一个变化:
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 ""; 替换第一个循环,可能会更简单。
您可以使用Enumerable.Range 生成数字并将它们转换为char 以生成A-Z。下一步是将它们结合起来。
【讨论】:
虽然在 PHP 中,但在 SO 中找到了这个。这会有帮助吗? Algorithm to get the excel-like column name of a number
【讨论】:
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() )
)
)
);
【讨论】:
这是一种方法。 :)
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();
【讨论】:
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);
}
}
【讨论】:
查看ASCII table 并记下字符的值。您应该能够计算出一个循环,将字符从 A 增加到 Z 的次数与复制字符所需的次数一样多。 :)
【讨论】:
你也可以试试这个。 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;
}
}
【讨论】:
为了补充弗拉德的回答,这里是 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)));
}
【讨论】: