C#迭代不断增长的多维数组

时间:2017-02-04 18:50:51

标签: c# arrays

想象一下,我想从A迭代到Z.我们将使用ForeachFor循环。达到Z后,我想从AA到ZZ迭代,所以从AA开始,然后到AB,AC ...... AZ,BA,BC..BZ..ZA,ZB,ZZ。在这一点上,我们将移动到三个chars,然后是4等,直到一个未定义的点。

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

问题:如何做到这一点?

注意,没有给出代码,因为我们都知道如何在数组上foreach和嵌套foreach循环。

6 个答案:

答案 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 "";
    }
 }

答案 1 :(得分:1)

这里有一些代码可以满足您的需求。以下是完整的解释,但总的来说,它利用了这样一个事实:一旦你完成了给定长度的所有字母,你就会做A,然后是整个序列,然后是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++;
        }
    }
}

有两种方法。第一个是你调用的那个,它将生成一个无限的字母序列。第二个是递归魔术。

第一个很简单。它有一个我们在多少个字母的数量,用该计数调用第二个方法,然后枚举通过它们返回它们。一旦完成一个大小的全部操作,它就会增加计数和循环。

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

如果计数大于1,它将循环通过字母A到Z,并且对于每个字母,它将比它更短的序列附加到A.然后对于B,依此类推。

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

序列将无限期地继续产生。因为它使用递归,理论上如果你的字母字符串变得太长就会开始堆栈溢出,但是在字符串中每个字母的一个递归级别,你需要在你需要担心之前得到很长的字符串(而且我怀疑如果你在一个循环中走得那么远,你会先遇到其他问题。

另一个关键点(如果您不知道)是yield return使用延迟执行,因此它将根据需要生成序列中的每个新元素,因此它只会生成您要求的任意数量的项目。如果你迭代五次,它只会产生A-E,并且不会在任何时候考虑接下来的事情而浪费。

答案 2 :(得分:1)

另一个生成器(将1添加到带radix == 26的数字:A代表0,B代表1,... {{1 } Z}:

25

测试

// 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); 

答案 3 :(得分:1)

要走的路是使用简单的递归方法。 C#是一种使用生成器来表达想法的好语言:

GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;

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负责递归生成序列。它可以是空的,也可以是一些字母与所有较短长度序列的串联。

答案 4 :(得分:0)

你的目标是从A到Z [A,...,Z]。 然后你要做多个for循环

例如:

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

答案 5 :(得分: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;
}