【问题标题】:Recursive C++ function not returning correct boolean value递归 C++ 函数未返回正确的布尔值
【发布时间】:2020-07-25 11:21:34
【问题描述】:

如果值是向量的前 n 个条目之一,则该函数应该返回 true,否则返回 false。我已经为此工作了一段时间,但无法弄清楚为什么它不能正常工作。

template <class T>
bool find(const vector<T> &v,  T value, int n) {
    //base case
    if (n == 0) {
        cout << "not here" << endl;
        return false;
    }
    //general case
    if (v[n] == value) {
        cout << v[n] << " == " << value << endl;
        return true;
    }
    cout << "find(" << "v" << ", " << value << ", " << n - 1 << ")" << endl;
    find(v, value, n - 1);
}

couts 只是因为我不擅长调试。以下是我对其进行的测试和结果:

vector<int> v = {1, 2, 3, 4, 5};
cout << boolalpha << find(v, 3, 4);

控制台:

find(v, 3, 3)
find(v, 3, 2)
3 == 3
false

显然,该函数正在查找匹配值,但我非常困惑为什么它仍然返回 false。

【问题讨论】:

  • 如果既不是n==0也不是v[n] == value,函数返回什么?
  • 除了缺少的return,您的函数永远不会查看v[0],因此如果它恰好在第一个元素中,将永远找不到该值。回想一下,前三个元素是v[0]v[1]v[2];但不是v[3]
  • 为什么不使用 for 循环?这里不需要递归函数,循环更容易阅读
  • @goaran 如果这不是练习,应该使用std::find
  • 一个向量可以容纳数千甚至数百万个元素并不是不合理的。为这样的容器编写递归查找函数是没有意义的,因为您会用尽堆栈空间来尝试查找元素。

标签: c++ recursion search vector function-definition


【解决方案1】:

你需要返回find的结果

return find(v, value, n - 1);

在你的函数中。

如果你打开警告,编译器会告诉你你做错了什么。

另外,您的基本情况似乎不正确。 0 是一个有效的索引。如果n-1,您应该停止。

与您的问题有关,使用递归方法在连续容器中查找元素似乎很奇怪。你为什么不试试类似的东西

std::find(v.begin(), v.begin() + n, value);

您可以将findv.begin() + n 的结果进行比较,以检查是否找到了该元素。

【讨论】:

    【解决方案2】:

    在这种情况下你忘记从函数中返回

    find(v, value, n - 1);
    

    无论如何,函数定义不正确。

    应该是这样的

    template <class T>
    bool find( const std::vector<T> &v,  const T &value, typename std::vector<T>::size_type n ) 
    {
        return v.size() < n || n == 0 ? false : v[n-1] == value || find( v, value, n - 1 );
    }
    

    这是一个演示程序。

    #include <iostream>
    #include <iomanip>
    #include <vector>
    
    template <class T>
    bool find( const std::vector<T> &v,  const T &value, typename std::vector<T>::size_type n ) 
    {
        return v.size() < n || n == 0 ? false : v[n-1] == value || find( v, value, n - 1 );
    }
    
    int main() 
    {
        std::vector<int> v = { 1, 2, 3, 4, 5 };
    
        std::cout << std::boolalpha << find( v, 5, v.size() ) << '\n';
        std::cout << std::boolalpha << find( v, 5, v.size() - 1 ) << '\n';
        std::cout << std::boolalpha << find( v, 1, 1 ) << '\n';
        std::cout << std::boolalpha << find( v, 2, 1 ) << '\n';
    
        return 0;
    }
    

    它的输出是

    true
    false
    true
    false
    

    至于您的函数实现,例如对于此调用,它将具有未定义的行为

    find( v, 5, v.size() )
    

    由于在此 if 语句中使用了等于 v.size() 的无效索引

    if (v[n] == value) {
        cout << v[n] << " == " << value << endl;
        return true;
    }
    

    实际上用户可以指定大于数组大小的第三个参数。因此,一种更灵活的方法是允许用户为第三个参数指定任何值,但在向量的现有元素中执行搜索。这是这样一个函数定义。

    #include <iostream>
    #include <iomanip>
    #include <vector>
    #include <algorithm>
    
    template <class T>
    bool find( const std::vector<T> &v,  const T &value, typename std::vector<T>::size_type n ) 
    {
        n = std::min( n, v.size() );
        return n != 0 && ( v[n-1] == value || find( v, value, n - 1 ) );
    }
    
    int main() 
    {
        std::vector<int> v = { 1, 2, 3, 4, 5 };
    
        std::cout << std::boolalpha << find( v, 5, 6 ) << '\n';
        std::cout << std::boolalpha << find( v, 5, 4 ) << '\n';
    
        return 0;
    }
    

    程序输出是

    true
    false
    

    【讨论】:

      猜你喜欢
      • 2018-10-10
      • 1970-01-01
      • 2015-04-12
      • 2015-02-08
      • 2013-09-11
      • 2011-06-04
      • 2021-01-06
      • 1970-01-01
      • 2018-08-11
      相关资源
      最近更新 更多