我编写了一个递归回文函数,在第一个代码中只接收一个单词,在第二个代码中接收一个句子。然而,意外的第二个代码给了我“超出范围”的错误。
这两个代码中使用了这个功能(工作正常):
pygame.quit()
在第一个代码中,即使我输入了一个非常长的字符串,它也按预期工作:
bool palindrome( string str, int first, int last )
{
if( first == str.size() - 1 ) //if string is a single alphabet.
return true;
if( str[ first ] == str[ last ] )
return palindrome( str.substr( first + 1, last - 1 ), first, last - 2 );
}
在第二个代码中,我需要将输入句子转换为单词,同时使所有字符都为小写(我在其他函数中执行所有这些操作)。我在第二个代码中输入了相同的字符串但仍然在页面底部出现错误:
int main()
{
string str = "madamhelloollehmadam";
palindrome( str, 0, str.size() - 1 ) ? cout << "palindrome!" << '\n' : cout << "not palindrome." << '\n';
}
这是我得到的错误(我不会得到这个错误,第一个代码得到一个单词而不是一个句子,但两个“回文”函数是相同的。我猜测“normalString”函数有问题但我无法发现任何尺寸差异...)
int main()
{
string str = "madam hello olleh madam"; //this becomes "madamhelloollehmadam" after going to "normalString" function.
palindrome( normalString(str), 0, normalString(str).size() - 1 ) ? cout << "palindrome!" << '\n' : cout << "not palindrome." << '\n';
}
这也是normalString函数:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::substr
Aborted
这是我的第二个代码:
string normalString( string str )
{
vector<string> vec;
for( int i = 0; i < str.size(); ++i )
vec.push_back( charToString(str[ i ]) );
for( int i = 0; i < vec.size(); ++i )
{
if( !isAlpha( vec[ i ] ) )
vec[ i ].erase();
if( isupper( stringToChar(vec[ i ]) ) )
vec[ i ] = charToString( tolower( stringToChar( vec[ i ] ) ) );
}
string str2 = vectorToString( vec );
return str2;
}
答案 0 :(得分:2)
此代码存在许多问题。
首先,让我们重写一下签名。由于palindrome
不需要字符串的副本,因此我们传入一个const引用。索引也应该更改为std::size_t
,因为这是用于索引字符串的类型。
bool palindrome(const std::string &str, std::size_t first, std::size_t last) {
接下来,我们需要处理字符串只有一个字符的情况......但 也很重要,以处理字符串为零的情况。这是原始代码:
// if (first == str.size() - 1) // Wrong!
首先,这并不是它所说的。我们正在处理的字符串的长度应该是从first
到last
,而不是从first
到size() - 1
(否则为什么last
甚至存在? )其次,如果size()
为0,这将无法工作。它会溢出!这是更正后的代码。
// Empty string, or only one character
std::size_t length = last - first;
if (length <= 1)
return true;
接下来,我们比较第一个和最后一个字符。但最后一个字符实际上并非str[last]
,而是str[last-1]
。
if (str[first] == str[last - 1])
由于我们有方便的first
和last
参数,因此我们使用它们而不是调用substr
:
return palindrome(str, first + 1, last - 1);
但是如果条件失败,我们必须记得要回来......
return false;
}
事实证明std::string
有push_back
,因此您不需要向量,isAlpha
可以更改为char
而不是string
{1}},这使它变得更加简单。
bool isAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
std::string normalString(std::string str) {
std::string result;
for (char c : str) {
if (isAlpha(c))
result.push_back(std::tolower(c));
}
return result;
}
同时删除了using namespace std;
#include <iostream>
#include <string>
#include <vector>
#include <locale>
bool palindrome(const std::string &, std::size_t, std::size_t);
std::string normalString(std::string);
int main() {
while (true) {
std::cout << "Enter a word or a sentence: ";
std::string str;
if (!(std::cin >> str))
break;
str = normalString(str);
if (palindrome(str, 0, str.size())) {
std::cout << str << " is palindrome!"
<< " (" << str << ")\n";
} else {
std::cout << str << " is not palindrome!"
<< " (" << normalString(str) << ") \n";
}
}
return 0;
}
bool isAlpha(char c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
std::string normalString(std::string str) {
std::string result;
for (char c : str) {
if (isAlpha(c))
result.push_back(std::tolower(c));
}
return result;
}
bool palindrome(const std::string &str, std::size_t first, std::size_t last) {
// Empty string, or only one character
std::size_t length = last - first;
if (length <= 1)
return true;
if (str[first] == str[last - 1])
return palindrome(str, first + 1, last - 1);
return false;
}
答案 1 :(得分:0)
在Visual Studio中使用Windows调试,您可以查明特定行的问题。
所以这就是你的问题:在函数normalString(string)
中你必须这样做:
for (int i = 0; i < vec.size(); ++i)
{
if (!isAlpha(vec[i]))
vec[i].erase();
else if (isupper(stringToChar(vec[i]))) //this is where your error was. use visual studio to debug your application
vec[i] = charToString(tolower(stringToChar(vec[i])));
}
你想在一个让你的程序崩溃的奇怪角色上使用函数isupper
。如果你使用else if语句,它会起作用,因为如果它不是alpha字符,它就不会尝试调用isupper()。
课程:使用Visual Studio调试模式
编辑:我相信你试图这样做isupper('{0}')
。 isupper()显然不喜欢字符串终止符(它&#39; ll崩溃)