为什么我的Palindrome函数会继续返回false?

时间:2015-04-29 15:35:18

标签: c++ string palindrome

我有一个包含以下内容的文本文件:

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;





}

3 个答案:

答案 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中仍然可以使代码相对简单易懂。