我有一个包含以下内容的文本文件:
1457887541
Madam
Able was I ere I saw Elba
Straw? No, too stupid a fad. I put soot on warts.
Class is cancelled today
当我运行程序时,我得到所有字符串返回false
并且无法找出原因。
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
using namespace std;
bool isPalindrome(string);
int main()
{
string input;
fstream nameFile;
nameFile.open("Xample.txt", ios::in);
if (nameFile)
{
cout << "Now reading from file: " << endl;
// Read an item from the file.
getline(nameFile, input);
// While the last read operation
// was successful, continue.
while (nameFile)
{
cout << input << endl;
//Palindrome function call
if(isPalindrome(input)){
cout << "It is a Palindrome :)/> " << endl;
}
else {
cout << "It is not a Palindrome :'( " << endl;
}
// Read the next string.
getline(nameFile, input);
}
//Close when completed
cout << "Done!" << endl;
nameFile.close();
}
else
{
cout << "ERROR: Cannot open file.\n";
}
return 0;
}
bool isPalindrome(string input){
int first = 0;
int last = input.length() - 1;
//begin loop to compare first position with last
while(last > first){
//loop if it is not a number or letter
while(!isalnum(input[first]) && !isalnum(input[last])){
first++;
last--;
}
if(tolower(input[first]) != tolower(input[last])){
return false;
}
last--;
first++;
}
return true;
}
答案 0 :(得分:2)
如果没有运行/调试代码,我认为问题出在您的算法中。这部分代码看起来像是为了解决空格和标点符号问题。
//loop if it is not a number or letter
while(!isalnum(input[first]) && !isalnum(input[last])){
first++;
last--;
}
但这不起作用。你正在跳过当前的第一个和最后一个字符,如果它们都不是字母字符,但是你应该只跳过一个或另一个字符,所以你应该将它分成两个if语句而不是一个循环。< / p>
答案 1 :(得分:2)
我只是尝试编辑代码并运行它,因为Bill说问题是你的逻辑。
while(!isalnum(input[first]) && !isalnum(input[last])){
first++;
last--;
}
如果输入[first]不是字母数字,则应仅增加它并在 last 的同时减少。
这是该函数的修正版本,看看它将更加清晰
bool isPalindrome(string input){
int first = 0;
int last = input.length() - 1;
while(last > first)
{
if(!isalnum(input[first]))
first++; //Increment only first
else if(!isalnum(input[last]))
last--; //Decrement only last
else if(tolower(input[first]) != tolower(input[last])){
return false;
}
else
{
last--;
first++;
}
}
return true;
}
答案 2 :(得分:2)
答案显然是#34;因为你的代码没有做你想的或想要的事情。 (并不是说它本身非常有用)。
除非你真的需要检查数据&#34;到位&#34;复制你关心的数据几乎肯定更容易也更容易理解,然后检查结果是否是回文:
bool is_palindrome(std::string const &input) {
std::string temp;
std::copy_if(input.begin(), input.end(), std::back_inserter(temp), isalnum);
return temp == std::string(temp.rbegin(), temp.rend());
}
如果在原地完成这项工作很重要,我仍然会尝试在逻辑上将我们不关心的&#34;跳过的字符分开&#34;部分来自&#34;检查结果是否是回文&#34;部分。一种方法是将过滤构建到一个特殊的迭代器中。举一个例子,将过滤封装到Boost filter_iterator
中仍然可以使代码相对简单易懂。