【问题标题】:How to use recursion in std::list?如何在 std::list 中使用递归?
【发布时间】:2015-05-21 04:32:22
【问题描述】:

我在执行这段代码时遇到了问题。此代码的第一个基本条件(用于在字符串列表中搜索字符串)不起作用。谢谢。

int string_check(list<string> l,list<string>::iterator it,string s)
{   
if(it==l.end()) return 0;
if(*it==s) return 1;
return(string_check(l,++it,s));
}

【问题讨论】:

  • 通过引用传递列表
  • 还有字符串。
  • 我在这里测试过,OP 的代码在这里工作。 g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2.

标签: c++ string recursion stdlist


【解决方案1】:

你需要改写int string_check(const list&lt;string&gt;&amp; l, const list&lt;string&gt;::iterator it&amp;, const string&amp; s)

否则,您将获取 std::list 和迭代器的值副本,因此对它们的任何修改都不会反映在调用者中。

我通过 constant 引用传递对象。这有助于程序稳定性,因为函数体不能修改传递的参数。我也以这种方式传递string,以防止不必要的值复制。

【讨论】:

    【解决方案2】:

    您按值传递列表,因此 l.end() 每次都是不同列表的结尾,而不是 it 来自的列表。

    要么通过引用传递列表;或传递结束迭代器而不是列表本身。这将是一个更灵活的解决方案,允许您将函数与特定容器类型分离并支持任何范围的输入迭代器:

    template <typename InIter, typename T>
    bool contains(InIter begin, InIter end, T const & value) {
        if (begin == end) return false;
        if (*begin == value) return true;
        return contains(++begin, end, value);
    }
    

    递归通常是个坏主意,因为堆栈通常很小,如果溢出会导致可怕的错误。除非这是实现此类功能的练习,否则请使用迭代:

    for (; begin != end; ++begin) {
        if (*begin == value) return true;
    }
    return false;
    

    或标准库:

    return std::find(begin, end, value) != end;
    

    【讨论】:

    • 加一个,比我的答案好得多。更多的是“STL”的做事方式。如果有的话,我会留下我的,以指出业余爱好者和专业人士之间的区别。
    【解决方案3】:

    我会以不同的方式定义函数。在列表中指定一对指定目标范围的迭代器就足够了。

    bool string_check( std::list<std::string>::const_iterator first,
                       std::list<std::string>::const_iterator last,
                       const std::string &s )
    {
        return ( first != last ) && 
               ( *first == s || string_check( ++first, last, s ) );
    } 
    

    也就是说,列表本身也不需要传递。

    您可以定义一个可以处理任何类型列表的模板函数。只有你应该选择的函数的名称更合适。 例如

    template <class InputIterator, class T>
    bool find( InputIterator first,
               InputIterator last,
               const T &value )
    {
        return ( first != last ) && 
               ( *first == value || string_check( ++first, last, value ) );
    } 
    

    至于你的函数实现,那么列表的第一个参数应该被声明为引用

    list<string> &l
    

    Moover 应该声明为 const 引用

    const list<string> &l
    

    该函数可以为常量列表调用。在这种情况下,您还必须更改迭代器的类型。

    【讨论】:

      猜你喜欢
      • 2012-07-05
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多