使用 C++ 的 Palindrome 程序的意外输出
undesired output of the Palindrome program using C++
所以我两周前开始学习 C++,我想构建一个程序来检查字符串是否为回文。
我尝试了不同的方法,包括以下方式的 str1==str2 方法:
#include<iostream>
#include<string>
using namespace std;
string empty;
string word;
bool inverse(string word)
{
for (int i=0;i<=word.length();i++)
{
empty+=word[word.length()-i];
}
return empty==word;
}
int main()
{
cout<<inverse("civic");
}
输出总是0
第二种方式:str1.compare(str2) 方法
#include<iostream>
#include<string>
using namespace std;
string empty;
string word;
bool inverse(string word)
{
for (int i=0;i<=word.length();i++)
{empty+=word[word.length()-i];}
if (word.compare(empty))
return true;
else
return false;
}
int main()
{
if (inverse(word)==true)
cout<<"is a palindrome";
else
cout<<"is not a palindrome";
cout<<inverse("ano");
cout<<inverse("madam");
}
输出总是:是回文1("palindrome"末尾有1个或2个)
即使字符串不是回文。
请向我解释我犯了哪些错误以及如何改正这些错误。
另外,如果我想让我的程序处理其中包含白色 space 的字符串,我该怎么做?
对于第一个,您需要更改
for (int i=0;i<=word.length();i++)
{empty+=word[word.length()-i];}
至此
for (int i=0;i<word.length();i++)
{empty+=word[word.length()-(i+1)];}
有几个问题
您的代码循环次数过多。例如,三个字母的单词应该循环三次,但您的代码循环了 4 次(i=0
、i=1
、i=2
和 i=3
)。要解决此问题,您需要更改最终条件以使用 <
而不是 <=
。
您计算对称指数的公式有误。例如,如果您有一个长度为 3 的单词,则字母为 word[0]
、word[1]
和 word[2]
。但是,您的代码使用 length - i
,对于 i=0
,这将使用超出该词允许限制的 word[3]
。您需要使用公式 length - 1 - i
而不是 length - i
.
进行索引
这两种错误在编程中都很常见,它们被称为 "off-by-one" 错误。请记住在编写代码时始终仔细检查边界条件,以便您的程序远离此类错误。
你的程序的行为将在这一行之后变得不确定:
for (int i = 0;i <= word.length(); i++)
empty += word[word.length() - i];
因为长度总是加最后一个元素(因为第一个索引是零), 当 i
是 0
, 那么: word[word.length()]
会给你元素 在 最后一个元素之后, 这是不可能的, 因此你的程序将调用未定义的行为,因为当 i
本身变成 word.length()
时 C/C++... word[word.length()]
也是可能的,因此更改 <=
(小于或等于到)到<
(小于)
所以,应该是:
for (int i = 0;i < word.length(); i++)
empty += word[word.length() - 1 - i];
所以我两周前开始学习 C++,我想构建一个程序来检查字符串是否为回文。 我尝试了不同的方法,包括以下方式的 str1==str2 方法:
#include<iostream>
#include<string>
using namespace std;
string empty;
string word;
bool inverse(string word)
{
for (int i=0;i<=word.length();i++)
{
empty+=word[word.length()-i];
}
return empty==word;
}
int main()
{
cout<<inverse("civic");
}
输出总是0
第二种方式:str1.compare(str2) 方法
#include<iostream>
#include<string>
using namespace std;
string empty;
string word;
bool inverse(string word)
{
for (int i=0;i<=word.length();i++)
{empty+=word[word.length()-i];}
if (word.compare(empty))
return true;
else
return false;
}
int main()
{
if (inverse(word)==true)
cout<<"is a palindrome";
else
cout<<"is not a palindrome";
cout<<inverse("ano");
cout<<inverse("madam");
}
输出总是:是回文1("palindrome"末尾有1个或2个) 即使字符串不是回文。
请向我解释我犯了哪些错误以及如何改正这些错误。 另外,如果我想让我的程序处理其中包含白色 space 的字符串,我该怎么做?
对于第一个,您需要更改
for (int i=0;i<=word.length();i++)
{empty+=word[word.length()-i];}
至此
for (int i=0;i<word.length();i++)
{empty+=word[word.length()-(i+1)];}
有几个问题
您的代码循环次数过多。例如,三个字母的单词应该循环三次,但您的代码循环了 4 次(
i=0
、i=1
、i=2
和i=3
)。要解决此问题,您需要更改最终条件以使用<
而不是<=
。您计算对称指数的公式有误。例如,如果您有一个长度为 3 的单词,则字母为
word[0]
、word[1]
和word[2]
。但是,您的代码使用length - i
,对于i=0
,这将使用超出该词允许限制的word[3]
。您需要使用公式length - 1 - i
而不是length - i
. 进行索引
这两种错误在编程中都很常见,它们被称为 "off-by-one" 错误。请记住在编写代码时始终仔细检查边界条件,以便您的程序远离此类错误。
你的程序的行为将在这一行之后变得不确定:
for (int i = 0;i <= word.length(); i++)
empty += word[word.length() - i];
因为长度总是加最后一个元素(因为第一个索引是零), 当 i
是 0
, 那么: word[word.length()]
会给你元素 在 最后一个元素之后, 这是不可能的, 因此你的程序将调用未定义的行为,因为当 i
本身变成 word.length()
时 C/C++... word[word.length()]
也是可能的,因此更改 <=
(小于或等于到)到<
(小于)
所以,应该是:
for (int i = 0;i < word.length(); i++)
empty += word[word.length() - 1 - i];