C++ 如何使用递归计算字符串中的元音

C++ 如何使用递归计算字符串中的元音,c++,recursion,C++,Recursion,我试图使用递归计算字符串中元音的数量。以下是我到目前为止的情况: int vowels(string str, int pos, int length) { if (str.length() == 0) return 0; switch (str[pos]) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'A':

我试图使用递归计算字符串中元音的数量。以下是我到目前为止的情况:

int vowels(string str, int pos, int length)
{
    if (str.length() == 0)
    return 0;

    switch (str[pos])
    {
      case 'a':
      case 'e':
      case 'i':
      case 'o':
      case 'u':
      case 'A':
      case 'E':
      case 'I':
      case 'O':
      case 'U':
        return 1 + vowels(str.substr(1), pos, length);
      default:
        return vowels(str.substr(1), pos, length);
    }
}

int main()
{
    string str;
    int len;

    cout << "Enter a string: ";
    getline(cin, str);
    cout << endl;

    len = static_cast<int>(str.length());

    cout << "Number of vowels in \"" << str << "\" = "
         << vowels(str, 0, len) << endl;

    return 0;
}
int元音(字符串str、int-pos、int-length)
{
如果(str.length()==0)
返回0;
开关(str[pos])
{
案例“a”:
案例“e”:
案例“i”:
案例“o”:
案例“u”:
案例“A”:
案例“E”:
案例“I”:
案例“O”:
案例“U”:
返回1+个元音(str.substr(1),pos,length);
违约:
返回元音(str.substr(1),pos,length);
}
}
int main()
{
字符串str;
内伦;

cout我将用以下方式定义函数

#include <cstring>
#include <string>

std::string::size_type count_vowels( const std::string &s, 
                                     std::string::size_type pos, 
                                     std::string::size_type length )
{
   const char *vowels = "aeiouAEIOU";

   if ( s.length() <= pos || length == 0 ) return 0;

   return ( s[pos] && std::strchr( vowels, s[pos] ) != 0 ) + 
          count_vowels( s, pos + 1, length - 1 );
}
#包括
#包括
std::string::size\u type count\u元音(const std::string&s,
标准::字符串::大小\类型位置,
标准::字符串::大小(类型长度)
{
常量字符*元音=“aeiouAEIOU”;

如果(s.length()似乎忘记了增加pos:

/* inside the vowels function switch statement */
return 1 + vowels(str.substr(1), pos+1, length);
    default:
return vowels(str.substr(1), pos+1, length);

此外,如果将递归结束条件更改为“pos==str.length()”,则根本不需要str.substr(…)。此外,如果跳过substr(…),请按常量引用传递std::string(这是一个好习惯)对于这个问题,你不应该使用递归。有时候,在C++开发中使用递归是明智的,但对于一般用途来说,缺少表示性能瓶颈的一个因素。一般来说,如果递归过程每次调用只调用一次,那么最好使用循环。。如果一个递归过程调用自身两次(例如,进入树型数据结构的左分支和右分支,或者可能计算斐波那契序列),则使用递归函数而不是循环可能更容易

这就是说,这显然是一项家庭作业,而明智的软件开发实践在这方面没有立足之地

传递<代码> POS < /C>和长度>代码>以及<代码>字符串 >似乎很愚蠢…C++已经为您提供了一个很好的通用工具,用于处理迭代器(和字符串只是一个迭代的字符集),以…迭代器的形式出现。 迭代器有效地将“位置”的概念封装在容器中。

string::begin()
获取指向字符串开头的迭代器,而
string::end()
获取指向结尾的迭代器。您可以取消对非结尾迭代器的引用以获取它指向的字符(非常类似于指针),并递增迭代器以将其前进到集合中的下一个元素

这里有一个简单计算字符的示例,但我相信您能够根据自己的需要进行调整

template<class Iterator>
int count_characters(Iterator begin, Iterator end)
{
    // if we're at the end of the string, there's nothing more to count
    if (begin == end)
        return 0;
    else // note the pre-increment here. post-increment won't work.
        return 1 + count_characters(++begin, end);
}
模板
int count_字符(迭代器开始、迭代器结束)
{
//如果我们在这条线的尽头,就没有什么可数的了
如果(开始==结束)
返回0;
else//注意此处的预增量。后增量将不起作用。
返回1+个计数字符(++开始,结束);
}
它可以这样使用:

std::string foo = "a phrase, yay";
std::cout << count_characters(foo.begin(), foo.end());
std::string foo=“一个短语,耶”;

std::cout如果你想在家庭作业中得到帮助,可以展示更多的工作。你的代码看起来不必要的复杂-你应该能够将其简化很多。这似乎效率非常低。使用递归是作业的要求吗?提示:使用辅助函数来实现递归,然后使用适当的方法从
元音
调用它ate初始条件。此外,您应该通过常量引用传递
string str
,以避免可怕的性能特征。@user3010694如果您不需要使用递归,那么就不要在此处使用它。这没有意义。不确定这是认真的还是出色的trolling。为什么测试's[pos]`(
s[pos]!=0
)?为什么strchr和no find_first of?@Dieter Lücking AFAIK strchr在搜索中包含字符“\0”。因此,如果字符串包含“\0”,则会在字符串文字中找到它。@vladfrommosco好吧,一些拼写错误现在已经修复,但同时增加pos和减少长度是行不通的。(您将在字符串的中间相遇并提前终止)+这个问题在当前状态下确实不值得回答。
std::string foo = "a phrase, yay";
std::cout << count_characters(foo.begin(), foo.end());