【问题标题】:Find common element using recursive and return as vector使用递归查找公共元素并作为向量返回
【发布时间】:2021-05-01 12:09:13
【问题描述】:

我正在尝试查找两个数组的共同元素,但我得到了错误的结果。

我的错误在哪里?好像一切正​​常。

template<class T>
bool contains(T arr,int size, int num){
    for(int i=0; i<size;++i)
        if(arr[i] == num)
            return true;
    return false;
}

我正在尝试使用尾递归:

template <class T>
vector<T> cElemet(T ar1[], int s1, T ar2[], int s2){

    vector<T> v;


    if(s1 > 0) 
        v = cElemet(ar1,s1-1,ar2,s2);


    if(contains(ar2,s2,ar1[s1-1])){
        cout << "+" << ar1[s1-1] ; 
        v.push_back(ar1[s1-1]);
    }

    return v;
}
int main(){
    
    int ar1[6] = {1,5,6,7,2,4};
    int ar2[6] = {6,3,9,4,5,8};

    std::vector<int> v = cElemet(ar1,6,ar2,6);

    cout <<endl;
    for(auto a : v)
        cout << a << " ";
    return 0;
}

【问题讨论】:

  • 它对我有用。我不知道你认为它有什么问题。
  • 未定义的行为(vide infra)有时似乎起作用。
  • 当我运行 OP 的代码(MSVC)时,我得到了这样的输出:8 5 6 4
  • 为什么ar1ar2 也不是std::vectors?尝试用向量和基于范围的 for 循环重写代码,你一开始就不会犯这个错误。
  • 这不是尾递归——尾调用是函数中发生的最后一件事。 (即使你重写它,C++ 中析构函数的存在也很容易将看起来像尾调用的东西变成非尾调用。)

标签: c++ templates recursion


【解决方案1】:

您的“递归结束”条件是“逐一”——它应该是 if (s1 &gt; 1) 而不是 if (s1 &gt; 0)

就目前而言,您最终调用cElemet 并使用0(来自s1 - 1)的值,然后,在该递归中,当s1 为零时,您尝试访问ar1[s1 - 1],这会导致未定义的行为。

将您的函数更改为以下可以解决问题 - 对于您的示例数组(即使我通过混淆数据值进行测试)。但是,1 大小的数组可能存在问题。

template <class T>
vector<T> cElemet(T ar1[], int s1, T ar2[], int s2)
{
    vector<T> v;
    if (s1 > 1) // Don't call recursively when s1 is 1 ...
        v = cElemet(ar1, s1 - 1, ar2, s2);

    if (contains(ar2, s2, ar1[s1 - 1])) { // ... or we have UB here.
        cout << "+" << ar1[s1 - 1];
        v.push_back(ar1[s1 - 1]);
    }
    return v;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 2016-11-26
    相关资源
    最近更新 更多