我的目标是查看两个数组(每个数组有四个项目)并将它们中出现的任何值放在向量中。
从技术上讲,我可以使用循环,比如
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只重新出现一次。
我理解为什么会出现这种重复。当我增加第二个数组的索引时,即使它经历了一个新的递归,我仍然允许第一个索引改变,就像在前一个递归中一样。因此,递增索引会分支不必要的额外递归。
我不知道如何解决它。有人可以帮我这个。
答案 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);
}