基于索引相等性跳过矢量迭代

时间:2018-06-02 06:52:40

标签: c++ vector

假设我有三个向量。

#include <vector>
vector<long> Alpha;
vector<long> Beta;
vector<long> Gamma;

让我们假设我已经用数字填充它们,而且我们知道它们的长度都是一样的。 (我们提前知道这个长度 - 让我们说它是3个。)

我最终想要的是所有总和Alpha[i] + Beta[j] + Gamma[k]中的最小值,以使ijk彼此不相等。< / p>

天真的方法看起来像这样:

#include <climits>

long min = LONG_MAX;

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        for (int k=0; k < 3; k++) {

            if (i != j && i != k && j != k) {
                long sum = Alpha[i] + Beta[j] + Gamma[k];
                if (sum < min)
                     min = sum;
            }
        }
    }
}

坦率地说,这段代码感觉不对。是否有更快和/或更优雅的方式 - 跳过冗余迭代的方法?

2 个答案:

答案 0 :(得分:2)

算法的计算复杂度为O(N^3)。您可以使用以下方法保存一小部分:

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if ( i == j )
           continue;

        long sum1 = Alpha[i] + Beta[j];
        for (int k=0; k < 3; k++) {    
            if (i != k && j != k) {
                long sum2 = sum1 + Gamma[k];
                if (sum2 < min)
                     min = sum2;
            }
        }
    }
}

然而,算法的复杂性仍为O(N^3)

如果没有if ( i == j )检查,最里面的循环将执行N^2次。通过该检查,您将能够避免最里面的循环N次。它将执行N(N-1)次。支票几乎不值得。

答案 1 :(得分:1)

如果你可以暂时修改输入向量,你可以将使用的值与向量的末尾交换,然后迭代向量的开头:

for (int i = 0; i < size; i++) {
    std::swap(Beta[i],Beta[size-1]);     // swap the used index with the last index
    std::swap(Gamma[i],Gamma[size-1]);
    for (int j = 0; j < size-1; j++) {     // don't try the last index
        std::swap(Gamma[j],Gamma[size-2]); // swap j with the 2nd-to-last index
        for (int k=0; k < size-2; k++) {   // don't try the 2 last indices
            long sum = Alpha[i] + Beta[j] + Gamma[k];
            if (sum < min) {
                min = sum;
            }
        }
        std::swap(Gamma[j],Gamma[size-2]); // restore values
    }
    std::swap(Beta[i],Beta[size-1]);       // restore values
    std::swap(Gamma[i],Gamma[size-1]);
}