生成一系列递归字母(如Excel列标题)

asi*_*ahi 1 c# recursion f#

长话短说我试图创建某种国际象棋库,可以用于任何规模的棋盘,可能是int.MaxValueint.MaxValue.生成无限的排名列表很容易:

    static IEnumerable<int> GetRankNumbers()
    {
        for(int i = 1; ; i++)
            yield return i;
    }
Run Code Online (Sandbox Code Playgroud)

但是为了生成文件信件,我目前正在这样做:

    static IEnumerable<string> GetFileLetters()
    {
        const string theLetters = "abcdefghjklmnopqrstuvwxyz"; // there is no 'i'.

        for(int i = 0; ; i++)
        {
            var factor = i / theLetters.Length;
            var index = i % theLetters.Length;

            var sb = new StringBuilder();
            sb.Append(theLetters[index]);

            for(int j = 0; j < factor; j++)
            {
                sb.Append(theLetters[index]);
            }

            yield return sb.ToString();
        }
    }
Run Code Online (Sandbox Code Playgroud)

产生以下内容:

var x = GetFileLetters().Take(100);
foreach(var item in x) Write(item + " ");

Output:
a b c d e f g h j k l m n o p q r s t u v w x y z aa bb cc dd ee ff gg hh jj kk ll mm nn oo pp qq rr ss tt uu vv ww xx yy zz aaa bbb ccc ddd eee fff ggg hhh jjj kkk lll mmm nnn ooo ppp qqq rrr sss ttt uuu vvv www xxx yyy zzz aaaa bbbb cccc dddd eeee ffff gggg hhhh jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz 
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,只有100件物品,它会迅速膨胀.我该怎么做才能将结果返回a, b, c, ..., z, aa, ab, ac, ... , az, ba, bb, .. etc

奖金问题:我如何在F#中做到这一点?

PS.我发现了一些类似的问题在这里,在这里,并在这里,但没有人有这样做IEnumerable,yield return和一个理论上无限一套像我想.最后一个是相当作弊(想到它我真的不需要更多......但我这样做是为了学习).

Fyo*_*kin 6

首先,让我们构造一个函数,它将产生一系列n字符组合.对于n = 1(基本情况),它将只生成一系列单个字符.对于n = 2,它将产生2个字符的所有组合.等等.

对于给定的n,我们如何生成所有n字符组合?首先我们在所有n-1字符组合前加上"a",然后我们在所有n-1字符组合前加上"b" ,依此类推:

let rec seqOfNChars n = 
  seq {
    for c in ['a' .. 'z'] do
      for s in seqOfNChars (n-1) do
        yield sprints "%c%s" c s
  }
Run Code Online (Sandbox Code Playgroud)

然后添加基本案例:

let rec seqOfNChars n = 
  seq {
    for c in ['a' .. 'z'] do
      if n <= 1 then
        yield string c
      else
        for s in seqOfNChars (n-1) do
          yield sprintf "%c%s" c s
  }
Run Code Online (Sandbox Code Playgroud)

现在我们有了这个功能,我们可以轻松地生成所有长度的所有组合的序列,从1开始:

let allHeaders = Seq.initInfinite ((+) 1) |> Seq.collect seqOfNChars
Run Code Online (Sandbox Code Playgroud)