C ++递归 - 如何确保我不重复相同的值

时间:2018-03-10 09:28:42

标签: c++ arrays algorithm c++11 recursion

我的目标是查看两个数组(每个数组有四个项目)并将它们中出现的任何值放在向量中。

从技术上讲,我可以使用循环,比如

vector<int> result;

for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
        if (array1[i] == array2[j] {
                result.push_back(array1[l]);
        }
    }
}

但是最近我学会了递归,我想尝试使用递归算法来解决这个问题。

void findOverLaps(int array1[4], int array2[4], int startIndex1, int startIndex2, vector<int> *resultVector) {
    if (startIndex1 > 3 || startIndex2 > 3) {
        return;
    }
    if (array1[startIndex1] == array2[startIndex2]) {
        resultVector->push_back(array1[startIndex1]);
    }

    findOverLaps(array1, array2, startIndex1 + 1, startIndex2, resultVector);
    findOverLaps(array1, array2, startIndex1, startIndex2 + 1, resultVector);
}

int main() {
    vector<int> result;
    findOverLaps(array1, array2, 0, 0, &result);
}

此代码确实找到了所有类似的值。问题是这个递归算法多次找到那些相同的值,即使它们在每个数组中只出现一次。

例如,如果我将两个数组:{1,2,3,4}和{5,6,2,8}传递到递归函数中,该函数将识别重复2次三次。但是,我只想让它看作一个,因为2只重新出现一次。

我理解为什么会出现这种重复。当我增加第二个数组的索引时,即使它经历了一个新的递归,我仍然允许第一个索引改变,就像在前一个递归中一样。因此,递增索引会分支不必要的额外递归。

我不知道如何解决它。有人可以帮我这个。

3 个答案:

答案 0 :(得分:2)

使用递归的显而易见的方法是使用递归排序算法(例如,QuickSort或自上而下的合并排序)在两个排序的数组上使用std::set_intersection之前对两个数组进行排序。

不幸的是,每个阵列中只有4个项目,QuickSort和合并排序都不是特别优化。使用插入排序会更好,这种排序几乎不适合递归实现(尽管如此,如果您想要足够严重,可以这样做。)

您现在使用的算法具有O(N 2 )复杂度。只要您只处理少量物品,这是相当无害的,但如果您可能需要处理大量物品(例如,每个阵列中数百个),则O(N log N)使用排序后跟set_intersection的复杂性将产生巨大的差异。

底线:递归很酷而且全部,但它并没有让我觉得这是解决这个特殊问题的一个特别好的方法。它可以被使用并使其正常工作,但我并不特别相信这样做会有很大的成就。

答案 1 :(得分:1)

正如Jerry在他的回答中已经指出的那样,我也认为在一般情况下排序和使用std::set_intersection是这样做的方法。

只需为递归函数添加解决方案,就可以这样做。

void findOverLaps(int array1[4], int array2[4], int startIndex1, int startIndex2, vector<int> *resultVector) {
    if (startIndex2 > 3) {
        startIndex1++;
        startIndex2 = 0;
    }
    if (startIndex1 > 3) {
        return;
    }
    if (array1[startIndex1] == array2[startIndex2]) {
        resultVector->push_back(array1[startIndex1]);
    }

    findOverLaps(array1, array2, startIndex1, startIndex2 + 1, resultVector);
}

答案 2 :(得分:0)

当递归函数达到索引的范围限制时,它不会重置该索引,而是返回到调用它的位置。超级的解决方案已经在某种程度上解决了这个问题。只是为了好玩,我正在添加一个解决方案,其中索引仅在对递归函数的调用中更改,并且从不在函数本身内:

void findOverLaps(int array1[4], int array2[4], int startIndex1, int startIndex2, vector<int> *resultVector) {

    if (startIndex2 > 3) {
        findOverLaps(array1, array2, startIndex1+1, 0, resultVector);
    }
    if (startIndex1 > 3 || startIndex2 > 3) {
        return;
    }
    if (array1[startIndex1] == array2[startIndex2]) {
        resultVector->push_back(array1[startIndex1]);
    }

    findOverLaps(array1, array2, startIndex1, startIndex2 + 1, resultVector);
}