在C ++中的'for循环'中改变初始化程序

时间:2016-03-24 13:29:35

标签: c++ arrays sorting

int i = 0;
for(; i<size-1; i++) {
    int temp = arr[i];
    arr[i] = arr[i+1];
    arr[i+1] = temp;
}

这里我从数组的第一个位置开始。如果在循环之后我需要再次执行for循环,其中for循环以数组的下一个位置开始。

与第一个for loop类似,从:Array [0]

开始

第二次迭代:数组[1]

第三次迭代:数组[2]

示例:

对于数组:1 2 3 4 5

表示i = 0:2 1 3 4 5,2 3 1 4 5 2 3 4 1 5 2 2 4 4 1

对于i = 1:1 3 2 4 5,1 3 4 2 5,1 3 4 5 2等等。

2 个答案:

答案 0 :(得分:2)

您可以将循环嵌套在彼此内部,包括内循环访问外循环的迭代器值的能力。因此:

for(int start = 0; start < size-1; start++) {
    for(int i = start; i < size-1; i++) {
        // Inner code on 'i'
    }
}

会以start增加值重复您的循环,因此重复使用较高的i初始值,直到您完成列表为止。

答案 1 :(得分:1)

假设您有一个例程来为给定长度 n 生成数组元素的所有可能排列。假设在处理完所有 n!排列之后,例程以初始顺序保留数组的 n 项。

问题:我们如何构建一个例程来使用(n + 1)元素对数组进行所有可能的排列?

答案:
生成初始 n 元素的所有排列,每次处理整个数组;这样我们就用相同的最后一项处理了所有 n!排列 现在,将(n + 1) -st项与其中一个 n 交换并重复置换 n 元素 - 我们得到另一个 n!使用新的最后一项进行排列 n 元素保留在它们之前的顺序中,因此将最后一个项目放回其初始位置并选择另一个项目放在数组的末尾。重申置换 n 项目。
等等。

请记住,每次调用后,例程都会以初始顺序离开 n -items数组。要在 n + 1 保留此属性,我们需要确保在(n + 1) -st迭代之后,最后将相同的元素放在数组的末尾。 n!排列。

这是你如何做到的:

void ProcessAllPermutations(int arr[], int arrLen, int permLen)
{
    if(permLen == 1)
        ProcessThePermutation(arr, arrLen);         // print the permutation
    else
    {
        int lastpos = permLen - 1;                  // last item position for swaps

        for(int pos = lastpos; pos >= 0; pos--)     // pos of item to swap with the last
        {
            swap(arr[pos], arr[lastpos]);           // put the chosen item at the end
            ProcessAllPermutations(arr, arrLen, permLen - 1);
            swap(arr[pos], arr[lastpos]);           // put the chosen item back at pos
        }
    }
}

以下是例行程序的示例:https://ideone.com/sXp35O

但请注意,这种方法非常无效:

  1. 仅在非常小的输入尺寸下,它可以在合理的时间内工作。排列的数量是数组长度的阶乘函数,并且它的增长速度快于指数增长,这使得实际的 BIG 测试次数。
  2. 例程没有短期回报。即使第一个或第二个排列是正确的结果,例程也将执行所有其余的 n!不必要的测试。当然,可以添加一个返回路径来打破迭代,但这会使代码有点难看。并且它不会带来显着的收益,因为例程必须平均进行 n!/ 2 测试。
  3. 每个生成的排列都出现在递归的最后一级深处。测试正确的结果需要从ProcessThePermutation内调用ProcessAllPermutations,因此很难用其他函数替换被调用者。每次需要另一种测试/处理方法/其他方法时,必须修改调用函数。或者,必须提供指向处理函数的指针(&#39;回调&#39;)并将其推送到所有递归,直到调用将发生的地方。这可能是由某个上下文对象中的虚函数间接完成的,所以它看起来很不错 - 但是无法避免在递归调用中传递额外数据的开销。
  4. 该例程还有另一个有趣的属性:它不依赖于数据值。永远不会比较数组的元素。这有时可能是一个优点:例程可以置换任何类型的对象,即使它们不具有可比性。另一方面,它无法检测重复,因此在相同的项目的情况下,它将产生重复的结果。在所有 n 相等项目的退化情况下,结果将是 n!相等的序列。
  5. 因此,如果您询问如何生成所有排列以检测已排序的排列,我必须回答: DON&#39; T。
    请学习有效的排序算法。