我们在这里谈论所谓的XY-Problem。
老师想要介绍递归函数。元音计数只是一些噪音。不幸的是,给定的示例是一个糟糕的示例,因为使用迭代方法可以更好地实现它。
递归只是增加了不必要的时间和空间复杂度。因此,在所有情况下,与简单循环相比,性能都更差。
如果老师想让你学习递归,你不妨先看看this description或that更实际的例子。
读完之后,你就会明白循环可以简单地转化为递归函数。
我不确定,为什么会有“低”和“高”参数。可能是因为使用了存储在 char 数组中的 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++ 的方向,并使用有意义的变量名和 cmets,那么我们可以想出:
#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 << "\n\nThe string contains "
<< std::count_if(text.begin(), text.end(), [](const char c){ return std::isalpha(c) && ((0x208222 >> (c & 0x1f)) & 1);})
<< " vowels.\n";
return 0;
}
玩得开心。 . .