使用递归查找字符串中的字符数

时间:2013-11-13 21:48:40

标签: c++ recursion

我需要使用递归来确定给定字符串中某个字符的出现次数。现在非递归函数非常简单。但是,当尝试使用递归时,我的程序运行时出错

short f_r(string, char);
int main()
{
    string str;
    char c;
    cout << "Enter a string: ";
    getline(cin,str);
    cout << "Enter a character: ";
    cin >> c;
    cout << "\nString: " << str << endl;
    cout << f_r(str,c) << endl;


    return 0;

}

short f_r(string str, char c)
{

    int pos = 0;
    pos = str.find(c, pos);
    if (pos >  str.length()) return 0;
    else
    {
        int count = 0;
        count++;
        pos++;
        return count + f_r(str,c);
    }

}

4 个答案:

答案 0 :(得分:1)

这个“程序”有太多问题无法提供快速修复。首先,请考虑以下事项:

  • 你的“递归”一直反复调用具有相同状态的函数,所以最终你会把堆栈吹掉。
  • 如果找不到字符,
  • string.find()会返回npos

答案 1 :(得分:1)

您的else分支会将整个字符串传递给递归调用。这将一直持续到堆栈溢出。您只需要在c的第一个实例之后传递字符串的一部分。您可以通过更改

来完成此操作
return count + f_r(str,c);

str = str.substr(pos, str.size()-pos);
return count + f_r(str,c);

另请注意,由于count始终为1,因此此块会更简单,因为

pos++;
str = str.substr(pos, str.size()-pos);
return 1 + f_r(str,c);

答案 2 :(得分:1)

问题分析

您实施中的基本问题是:

  • 未能为发现的位置使用正确的数据类型
  • 终止递归的条件不正确
  • 不正确的递归参数(您传递相同的参数)。

<强>解决方案

那就是说,这个功能比你想象的要简单:

std::size_t f_r(const std::string& s, char c)
{
    std::string::size_type pos = s.find(c);
    return (pos == std::string::npos) ? 0 : (1 + f_r(s.substr(pos+1), c));
}

请注意以下事项:

  • 使用std::string::size_type进行位置计算
  • 如果没有返回任何值,则通过与std::string::npos进行比较来终止递归,并返回0作为最终递归调用的结果。
  • 将原始子字符串作为参数传递给递归调用。此子字符串包括传递 pos中发现的位置的所有剩余字符。

非递归解决方案

我意识到你的任务是递归地执行此操作,但我想确保你知道如何迭代地完成它而不必自己编写循环。 C ++标准库包含一个名为std::count的算法,该算法完全这样做,但是只有一次传递,没有像substr()那样的子分配,也没有递归在所有:

std::size_t f_r(const std::string& s, char c)
{
    return std::count(s.begin(), s.end(), c);
}

是的,它确实使f_r()的理由变得毫无意义。

答案 3 :(得分:0)

我会使用静态变量编写函数。

std::string::size_type f_r( const std::string &s, char c )
{
    static std::string::size_type pos;

    pos = s.find( c, pos );

    return ( pos == std::string::npos ? pos = 0 : ( ++pos, 1 + f_r( s, c ) ) );
}