Jon*_*eet 29
第一次努力,只有az然后aa-zz
public static IEnumerable<string> GetExcelColumns()
{
for (char c = 'a'; c <= 'z'; c++)
{
yield return c.ToString();
}
char[] chars = new char[2];
for (char high = 'a'; high <= 'z'; high++)
{
chars[0] = high;
for (char low = 'a'; low <= 'z'; low++)
{
chars[1] = low;
yield return new string(chars);
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,这将停在'zz'.当然,就循环而言,这里有一些丑陋的重复.幸运的是,这很容易修复 - 它也可以更灵活:
第二次尝试:更灵活的字母表
private const string Alphabet = "abcdefghijklmnopqrstuvwxyz";
public static IEnumerable<string> GetExcelColumns()
{
return GetExcelColumns(Alphabet);
}
public static IEnumerable<string> GetExcelColumns(string alphabet)
{
foreach(char c in alphabet)
{
yield return c.ToString();
}
char[] chars = new char[2];
foreach(char high in alphabet)
{
chars[0] = high;
foreach(char low in alphabet)
{
chars[1] = low;
yield return new string(chars);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果你想生成a,b,c,d,aa,ab,ac,ad,ba,...你打电话GetExcelColumns("abcd").
第三次尝试(进一步修订) - 无限序列
public static IEnumerable<string> GetExcelColumns(string alphabet)
{
int length = 0;
char[] chars = null;
int[] indexes = null;
while (true)
{
int position = length-1;
// Try to increment the least significant
// value.
while (position >= 0)
{
indexes[position]++;
if (indexes[position] == alphabet.Length)
{
for (int i=position; i < length; i++)
{
indexes[i] = 0;
chars[i] = alphabet[0];
}
position--;
}
else
{
chars[position] = alphabet[indexes[position]];
break;
}
}
// If we got all the way to the start of the array,
// we need an extra value
if (position == -1)
{
length++;
chars = new char[length];
indexes = new int[length];
for (int i=0; i < length; i++)
{
chars[i] = alphabet[0];
}
}
yield return new string(chars);
}
}
Run Code Online (Sandbox Code Playgroud)
它可能是使用递归的更干净的代码,但它不会那么有效.
请注意,如果您想在某个点停止,您可以使用LINQ:
var query = GetExcelColumns().TakeWhile(x => x != "zzz");
Run Code Online (Sandbox Code Playgroud)
"重新启动"迭代器
要从给定点重新启动迭代器,您确实可以SkipWhile按照软件jedi的建议使用.当然,那效率很低.如果你能够在调用之间保持任何状态,你可以保留迭代器(对于任一解决方案):
using (IEnumerator<string> iterator = GetExcelColumns())
{
iterator.MoveNext();
string firstAttempt = iterator.Current;
if (someCondition)
{
iterator.MoveNext();
string secondAttempt = iterator.Current;
// etc
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以构建代码以使用foreach任何方式,只需突破您可以实际使用的第一个值.
The*_*edi 22
编辑:完全按照OP的最新编辑要求完成
这是最简单的解决方案,并经过测试:
static void Main(string[] args)
{
Console.WriteLine(GetNextBase26("a"));
Console.WriteLine(GetNextBase26("bnc"));
}
private static string GetNextBase26(string a)
{
return Base26Sequence().SkipWhile(x => x != a).Skip(1).First();
}
private static IEnumerable<string> Base26Sequence()
{
long i = 0L;
while (true)
yield return Base26Encode(i++);
}
private static char[] base26Chars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
private static string Base26Encode(Int64 value)
{
string returnValue = null;
do
{
returnValue = base26Chars[value % 26] + returnValue;
value /= 26;
} while (value-- != 0);
return returnValue;
}
Run Code Online (Sandbox Code Playgroud)