计算元音的递归函数

  • 本文关键字:递归函数 计算 c++
  • 更新时间 :
  • 英文 :


我有一个任务,要求我">写一个递归函数vowels(s,low,high),返回输入字符串s[]中元音的个数。";我们还受到">的限制,不要使用c++字符串类型。使用cin.get()将字符一次一个地读入数组。";我想我解决了手头的任务,但它不编译所以我不确定。如果有人能帮助我,告诉我如何修复我的错误,以及我对我的解决方案所做的任何错误,那将是伟大的。

这是我的错误信息。

***main.cpp:24:37: error: invalid conversion from ‘char*’ to ‘char’ [-fpermissive]
vowelCount = vowels(s, low, high);**
下面是我的代码:
#include <iostream>
#include <cstring>
using namespace std;
int vowels(char, int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
if (s[low] == 'a' || 'A' || 'e' || 'E' || 'i' || 'I' || 'o' || 'O' || 'u' || 'U') {
return 1 + vowels(s, low + 1, high - 1);
} else {
return vowels(s, low + 1, high - 1);
}
}

我们这里讨论的是所谓的xy问题。

老师想讲递归函数。元音计数只是一些杂音。不幸的是,给出的例子是一个糟糕的例子,因为它可以通过迭代方法更好地实现。

递归只是增加了不必要的时间和空间复杂性。因此,在所有情况下,与简单循环相比,性能更差。

如果老师想让你学习递归,你可能想先看看这个描述或更实际的例子。

看完这里,你就会明白循环可以简单地转换成递归函数。

我不确定,为什么有一个"低"和一个"高"字;参数。可能是因为C字符串存储在字符数组中(这在c++中是无意义的)。我怀疑应该建立2个自我调用,函数应该从字符串的开始和结束走到中间。这甚至会进一步降低性能。因此,让我们假设标准情况。


在你的比较问题旁边。你写的是错的。c++中正确的比较应该是:

if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') || 
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') || 
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') || 
(s[low] == 'U'))

当然,没有人会写这么长的语句,因为你可以简单地计算,不需要任何比较,如果一个ASCII字符是元音。你可以简单地写:

if (std::isalpha(s[low]) && ((0x208222 >> (s[low] & 0x1f)) & 1))

就是这样。如果你感兴趣,我可以稍后解释这个理论,但这个例子不需要。

那么,接下来,你的递归函数是危险的错误,因为它没有结束条件。它将永远运行,或者直到堆栈溢出。

所以,你需要重做,它可以这样做:

#include <iostream>
#include <cstring>
using namespace std;
int vowels(char[], int, int);
int main()
{
char s[500];
int high,
vowelCount,
low = 0;
cout << "Enter a string of characters: ";
cin.get(s, 500);
high = strlen(s);
vowelCount = vowels(s, low, high);
cout << "The string contains " << vowelCount << " vowels." << endl;
return 0;
}
int vowels(char s[], int low, int high)
{
int sum = 0;
if (low != high) {
if ((s[low] == 'a') || (s[low] == 'A') || (s[low] == 'e') || 
(s[low] == 'E') || (s[low] == 'i') || (s[low] == 'I') || 
(s[low] == 'o') || (s[low] == 'O') || (s[low] == 'u') || 
(s[low] == 'U')) 
{
++sum; 
}
sum += vowels(s,low+1,high);
}
return sum;
}

如果我们再向c++的方向迈进一点,使用有意义的变量名和注释,那么我们可以得出这样的结果:

#include <iostream>
#include <cstring>
// A recursive function to count the vowels in a rang of a text
int countVowelsRecursive(char textToEvaluate[], unsigned int startPositionForEvaluation, unsigned int endPositionOfText)
{
// Here we will store the number of vowels. We will use tail recursion 
// So, the overall calculation will be done at the end 
unsigned int numberOfVowelsInThisRecursion = 0u;

// Now we are evaluating this character from the text
const char currentChar = textToEvaluate[startPositionForEvaluation];

// Check, for the end of recursion condition
if (startPositionForEvaluation != endPositionOfText) {
// Check, if it is a vowel
if ((currentChar == 'a') || (currentChar == 'A') || (currentChar == 'e') || 
(currentChar == 'E') || (currentChar == 'i') || (currentChar == 'I') || 
(currentChar == 'o') || (currentChar == 'O') || (currentChar == 'u') || 
(currentChar == 'U')) 
{
// Vowel found. Increase counter by one 
++numberOfVowelsInThisRecursion; 
}
// Tail recursion. Self call, starting at next position of the string
numberOfVowelsInThisRecursion += 
countVowelsRecursive(textToEvaluate,startPositionForEvaluation + 1, endPositionOfText);
}
// This will be the final result
return numberOfVowelsInThisRecursion;
}
// We will allow a maximal input text length like this
constexpr unsigned int MaxTextLength = 500u;
// Driver code / test function
int main()
{
// Here we will store the text from the user 
char text[MaxTextLength]{};

// Give instructions and get the text
std::cout << "Enter a string of characters: ";
std::cin.get(text, MaxTextLength);
// Set text parameters for the evaluation 
unsigned int startOfText = 0u;
unsigned int endOfText = static_cast<unsigned int>(strlen(text));

// Calculate the vowels
unsigned int vowelCount = countVowelsRecursive(text, startOfText, endOfText);
// Show result to user 
std::cout << "The string contains " << vowelCount << " vowels." << std::endl;
return 0;
}

如果允许使用c++的话,我们可以这样写:

#include <iostream>
#include <string>
#include <algorithm>
int main()
{
// Give instructions and get the text
std::cout << "nEnter a text:n";
if (std::string text{}; std::getline(std::cin, text))
// Show result to user 
std::cout << "nnThe string contains " 
<< std::count_if(text.begin(), text.end(), [](const char c){ return std::isalpha(c) && ((0x208222 >> (c & 0x1f)) & 1);})
<< " vowels.n";
return 0;
}

玩得开心…

最新更新