Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Language agnostic 如何简化这个循环?_Language Agnostic_Loops_For Loop - Fatal编程技术网

Language agnostic 如何简化这个循环?

Language agnostic 如何简化这个循环?,language-agnostic,loops,for-loop,Language Agnostic,Loops,For Loop,考虑一个数组a[i],i=0,1,…,g,其中g可以是任何给定的数字,a[0]=1 for a[1]=a[0]+1 to 1 do for a[2]=a[1]+1 to 3 do for a[3]=a[2]+1 to 5 do ... for a[g]=a[g-1]+1 to 2g-1 do #print a[1],a[2],...a[g]# 问题是每次我们更改g的值时,我们都需要修改代码,上面的循环。这

考虑一个数组
a[i]
i=0,1,…,g
,其中
g
可以是任何给定的数字,
a[0]=1

for a[1]=a[0]+1 to 1 do
   for a[2]=a[1]+1 to 3 do
      for a[3]=a[2]+1 to 5 do
         ...
            for a[g]=a[g-1]+1 to 2g-1 do
               #print a[1],a[2],...a[g]#

问题是每次我们更改
g
的值时,我们都需要修改代码,上面的循环。这不是一个好代码。

递归是解决这个问题的一种方法(尽管我很喜欢看到迭代解决方案)

警告,下面是未测试的代码

template<typename A, unsigned int Size>
void recurse(A (&arr)[Size],int level, int g)
{
   if (level > g) 
   { 
     // I am at the bottom level, do stuff here
     return;
   }

   for (arr[level] = arr[level-1]+1; arr[level] < 2 * level -1; arr[level]++)
   {

      recurse(copy,level+1,g);
   }
}
模板
无效递归(A(&arr)[Size],int-level,int-g)
{
如果(级别>g)
{ 
//我在底层,在这里做事
返回;
}
对于(arr[level]=arr[level-1]+1;arr[level]<2*level-1;arr[level]++)
{
递归(复制,级别+1,g);
}
}

然后用递归调用
recurse(arr,1,g)

我想说的是,您首先不需要嵌套循环。相反,您只需要调用一个合适的函数,将当前嵌套级别、最大嵌套级别(即
g
)、循环的开始以及任何需要作为计算上下文的内容作为参数:

void process(int level, int g, int start, T& context) {
    if (level != g) {
        for (int a(start + 1), end(2 * level - 1); a < end; ++a) {
            process(level + 1, g, a, context);
        }
    }
    else {
        computation goes here
    }
}
void流程(int-level、int-g、int-start、T&context){
如果(级别!=g){
对于(INTA(开始+1),结束(2*级别-1);a
想象你用一组数字来表示数字。例如,682将是[6,8,2]

如果你想从0数到999,你可以写:

for (int n[0] = 0; n[0] <= 9; ++n[0])
    for (int n[1] = 0; n[1] <= 9; ++n[1])
        for (int n[2] = 0; n[2] <= 9; ++n[2])
            // Do something with three digit number n here

你有三种语言:C++、Matlab和Mathematica,你想用哪种语言?欢迎任何语言。注意:如果G太大,你会得到一个堆栈溢出(LOL…站点名称)。我添加了一个迭代的解决方案。这个嵌套函数很棒。谢谢,伊森。
static void Print(int[] a, int n, ref int count)
{
    ++count;
    Console.Write("{0} ", count);
    for (int i = 0; i <= n; ++i)
    {
        Console.Write("{0} ", a[i]);
    }
    Console.WriteLine();
}

private static void InitialiseRight(int[] a, int startIndex, int g)
{
    for (int i = startIndex; i <= g; ++i)
        a[i] = a[i - 1] + 1;
}

static void Main(string[] args)
{
    const int g = 5;

    // Old method
    int count = 0;
    int[] a = new int[g + 1];
    a[0] = 1;
    for (a[1] = a[0] + 1; a[1] <= 2; ++a[1])
        for (a[2] = a[1] + 1; a[2] <= 3; ++a[2])
            for (a[3] = a[2] + 1; a[3] <= 5; ++a[3])
                for (a[4] = a[3] + 1; a[4] <= 7; ++a[4])
                    for (a[5] = a[4] + 1; a[5] <= 9; ++a[5])
                        Print(a, g, ref count);

    Console.WriteLine();
    count = 0;

    // New method

    // Initialise array
    a[0] = 1;
    InitialiseRight(a, 1, g);

    int index = g;
    // Loop until all "digits" have overflowed
    while (index != 0)
    {
        // Do processing here
        Print(a, g, ref count);

        // "Add one" to array
        index = g;
        bool carry = true;
        while ((index > 0) && carry)
        {
            carry = false;

            ++a[index];
            if (a[index] > 2 * index - 1)
            {
                --index;
                carry = true;
            }
        }
        // Re-initialise digits that overflowed.
        if (index != g)
            InitialiseRight(a, index + 1, g);
    }
}