2017-02-04 25 views
2

想象一下,我想从A迭代到Z.我们将使用ForeachFor循环。获得Z后,我想从AA到ZZ迭代,所以它从AA开始,然后到AB,AC ... AZ,BA,BC..BZ..ZA,ZB,ZZ。在这一点上,我们将移动到三个chars,然后是4等到一个未定义的点。C#迭代一个不断增长的多维数组

因为我们没有为数组定义的长度,我们不能使用嵌套循环for ...所以

问题:如何才能做到这一点?

请注意,没有给出代码,因为我们都知道如何在阵列上嵌套foreach并嵌套foreach循环。

回答

1

要走的路是使用简单的递归方法。 C#是提出一个想法与使用发电机的良好的语言:

private static IEnumerable<string> EnumerateLetters(int length) { 
    for (int i = 1; i <= length; i++) { 
     foreach (var letters in EnumerateLettersExact(i)) {     
      yield return letters; 
     } 
    } 
} 

private static IEnumerable<string> EnumerateLettersExact(int length) { 
    if (length == 0) { 
     yield return ""; 
    } 
    else { 
     for (char c = 'A'; c <= 'Z'; ++c) { 
      foreach (var letters in EnumerateLettersExact(length - 1)) { 
       yield return c + letters; 
      } 
     }  
    } 
} 

private static void Main(string[] args) { 
    foreach (var letters in EnumerateLetters(2)) { 
     Console.Write($"{letters} "); 
    } 
} 

EnumerateLetters生成的字母连续序列。该参数决定您想要请求序列的长度。

EnumerateLettersExact负责递归生成序列。它可以是空的,也可以是一些字母与所有长度较短的序列的连接。

0

Your're即将有一个数组从A到Z [A,...,Z]。 然后你要进行多次的循环

例如:

PSEUDOCODE 
foreach(in array){ 
    first = declare first variable (array) 
    foreach(in array{ 
      second =declare 2nd variable (array) 
      return first + second 
    } 
} 
+0

不幸的是,这意味着我需要知道我需要多少嵌套for循环。它可能是100个循环,实际上嵌套太多了。 –

+0

@Dave Gorden在开始之前,你知道你想要的循环数量吗? –

+0

否迭代次数未知。 –

1

你可以做这样的事情,它给了我无休止的模式的输出(对不起,没有确切的模式,但你知道如何做到这一点)

public static IEnumerable<string> Produce() 
{ 
    string seed = "A"; 
    int i = 0; 
    while (true) 
    { 
     yield return String.Join("", Enumerable.Repeat(seed, i));     
     if (seed == "Z") 
     { 
      seed = "A"; 
      i++; 
     } 
     else 
     { 
      seed = ((char)(seed[0]+1)).ToString(); 
     } 
    } 
} 

而且比:

foreach (var s in Produce()) 
{ 
    //Do something 
} 

编辑我所愿意用这种方法输出:

public static IEnumerable<string> Produce() 
{ 
    int i = 1; 
    while (true) 
    { 
     foreach(var c in produceAmount(i)) 
     { 
      yield return c; 
     } 
     i++; 
    } 
} 

private static IEnumerable<string> produceAmount(int i) 
{ 
    var firstRow = Enumerable.Range('A', 'Z' - 'A'+1).Select(x => ((char)x).ToString()); 
    if (i >= 1) 
    { 
     var second = produceAmount(i - 1); 
     foreach (var c in firstRow) 
     { 
      foreach (var s in second) 
      { 
       yield return c + s; 
      } 
     } 
    } 
    else 
    { 
     yield return ""; 
    } 
} 
+0

AA AA,BB,CC,DD(在很多空白之后 - 你需要从1开始),然后你的第二个更准确地AA,AB ... AZ,但是然后去BZ,CZ,DZ ...... – Chris

1

下面是一些代码,将你想要做什么。完整的解释如下,但总之它需要的事实,一旦你做了给定长度的所有字母,你做了之后是整个序列再然后是B,然后再对整个序列的优势,等

private IEnumerable<string> EnumerateLetters() 
{ 
    int count = 1; 
    while (true) 
    { 
     foreach(var letters in EnumerateLetters(count)) 
     { 
      yield return letters; 
     } 
     count++; 
    } 
} 

private IEnumerable<string> EnumerateLetters(int count) 
{ 
    if (count==0) 
    { 
     yield return String.Empty; 
    } 
    else 
    { 
     char letter = 'A'; 
     while(letter<='Z') 
     { 
      foreach(var letters in EnumerateLetters(count-1)) 
      { 
       yield return letter+letters; 
      } 
      letter++; 
     } 
    } 
} 

有两种方法。第一个是你打电话的那个,并且会产生一个无限的字母序列。第二个是递归魔术。

第一个很简单。它会计算出我们有多少个字母,用这个数字调用第二个方法,然后通过它们枚举返回它们。一旦它完成了所有的一个尺寸,它增加了计数和循环。

第二种方法是做魔术的方法。它会计算生成的字符串中的字母数。如果计数为零,则返回空字符串并中断。

如果计数超过一个,它将循环遍历字母A到Z,并且对于每个字母它会将它比序列短一些的顺序追加到A.然后对于B等等。

然后这将继续无限期地继续。

该序列将无限期地持续生成。因为它使用递归,所以如果你的字符串变得太长,但是在字符串中的每个字母的递归的一个级别,你将需要在很长的字符串之前起动,然后你需要担心它(我怀疑你是否在循环中走了那么远,你会首先遇到其他问题)。

另一个关键点(如果您不知道)是yield return使用延迟执行,因此它会根据需要在序列中生成每个新元素,因此它只会生成尽可能多的项目。如果你迭代五次,它只会产生A-E,并且不会浪费任何时间去思考接下来会发生什么。

1

另一个发生器(添加1多项与radix == 26A1代表0,B,... Z25):

// please, notice, that Generator() can potentially spawn ifinitely many items 
private static IEnumerable<String> Generator() { 
    char[] data = new char[] { 'A' }; // number to start with - "A" 

    while (true) { 
    yield return new string(data); 

    // trying to add one 
    for (int i = data.Length - 1; i >= 0; --i) 
     if (data[i] == 'Z') 
     data[i] = 'A'; 
     else { 
     data[i] = (char) (data[i] + 1); 

     break; 
     } 

    // have we exhausted N-length numbers? 
    if (data.All(item => item == 'A')) 
     data = Enumerable 
     .Repeat('A', data.Length + 1) // ... continue with N + 1-length numbers 
     .ToArray(); 
    } 
} 

测试

// take first 1000 items: 
    foreach (var item in Generator().Take(1000)) 
    Console.WriteLine(item); 

成果

A 
    B 
    C 
    .. 
    X 
    Y 
    Z 
    AA 
    AB 
    .. 
    AZ 
    BA 
    BB 
    BC 
    .. 
    ZY 
    ZZ 
    AAA 
    AAB 
    AAC 
    .. 
    ALK 
    ALL 
0

请尝试以下操作。这是一种为给定数字生成适当字符串的方法。你可以为你想要的迭代次数写一个for循环。

string SingleEntry(int number) 
{ 
    char[] array = " ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToArray(); 
    Stack<string> entry = new Stack<string>(); 
    List<string> list = new List<string>(); 
    int bas = 26; 

    int remainder = number, index = 0; 
    do 
    { 
     if ((remainder % bas) == 0) 
     { 
      index = bas; 
      remainder--; 
     } 
     else 
      index = remainder % bas; 

     entry.Push(array[index].ToString()); 
     remainder = remainder/bas; 
    } 
    while (remainder != 0); 

    string s = ""; 
    while (entry.Count > 0) 
    { 
     s += entry.Pop(); 
    } 
    return s; 
}