【问题标题】:Determine if a string is a palindrome without changing input在不更改输入的情况下确定字符串是否为回文
【发布时间】:2014-02-02 04:11:12
【问题描述】:

我正在尝试用 C++ 编写一个程序,它将一个字符串作为标准 cin 输入的输入,并确定输入是否为回文。我无法以任何方式更改字符串,也无法复制它。

代码必须包含类似bool isPalindrome( const char* x){}

下面列出了我的尝试。

#include <cctype>
#include <iostream>
#include <string>

using namespace std;

bool isPalindrome( const char* x)
{
  string str = *x;
  int n = str.length();
  for (int i = 0; i < n; ++i)
  {
    int j = 0;
    while (isalpha(str[i]))
    {
      if (isalpha(str[n-j-1])) 
      {
        if (tolower(str[i]) == tolower(str[n-j-1]))
          return true;
        else
          return false;
      }
      j +=  1;
    }
  }
  return true;
}

int main()
{
  string str;
  cout << "Enter your string: ";
  getline (cin, str);
  const char * x ;
  x = &str;
  if (isPalindrome(x) == true)
  {
    cout << "Yes it is!" << endl;
  }
  else
  {
    cout << "No, it's not." << endl;
  }
  cout << str << endl;
  return 0;
}

我不是最好的 C++ 程序员,指针的使用对我来说仍然有点困惑。参数const char * x 是否意味着输入被初始化为值不变的指针?任何帮助是极大的赞赏!

编辑:我忘了提...输入可能包含标点符号,但仍然可以是回文。例如“女士,我是亚当!”是回文。但是我不能从字符串中删除标点符号,因为不允许更改字符串。

【问题讨论】:

  • 这个任务根本不需要指针。
  • @user3261977:一种明显的方法是使用迭代器。
  • 为什么不能复制字符串?无论如何,只需通过递增迭代器来跳过标点和空格

标签: c++ pointers palindrome


【解决方案1】:

试试这个方法:

bool isPalindrome(const string& s)
{
    int a = 0;
    int b = s.size()-1;
    while(a<b)
    {
        if(s[a] != s[b]) return false;
        ++a;
        --b;
    }
    return true;
}

编辑:关于你的第二个问题:
const char * x 是指向数组的指针,其中元素是const
char * x 是指向数组的指针,char * const xconst 指向数组的指针,
const char * const xconst 指向数组的指针,其中元素是 const

EDIT2: 看起来您的代码中几乎包含它,但您返回 true 太快了,after you find a single character match。但是,当您已经使用 C++ string 时,不要使用 char *。如果只使用string 对象,可以使代码更清晰。

这是我如何有效地跳过非字母字符的方法:

bool isPalindrome(const string& s)
{
    int a = -1; // points before the first character
    int b = s.size(); // points after the last character
    for(;;)
    {
        // in each iteration shift `a` and `b` at least by one
        do ++a; while(a<b && !isalpha(s[a]));
        do --b; while(a<b && !isalpha(s[b]));

        if(a >= b) return true;
        if(toupper(s[a]) != toupper(s[b])) return false;
    }
}

或者效率不高,但可能更难产生错误(哦,但它复制了字符串,而你不希望这样):

#include <algorithm>

bool badchar(char c)
{
    return !isalpha(c);
}

bool isPalindrome2(const string& s)
{
    string copy(s);
    transform(s.begin(), s.end(), copy.begin(), ::toupper);
    copy.erase(remove_if(copy.begin(), copy.end(), badchar), copy.end());
    string rev = copy;
    reverse(rev.begin(), rev.end());
    return copy == rev;
}

我更喜欢第一种方式。

【讨论】:

  • 我忘了提...输入可能包含标点符号,但仍然可以是回文。例如“女士,我是亚当!”是回文。但是我不能从字符串中删除标点符号,因为不允许更改字符串。
【解决方案2】:

逻辑很简单。从中间分开字符串。比较从头到尾,以此类推直到中间。如果字符在任何时候都不相等,则它不是回文。

代码 sn-p(未经测试):

char string[] = "level";
int length;

length = strlen(string);

for(int i = 0, j = length - 1; i < (length / 2) ; i++, j--) {
    if(string[i] != string[j]) {
        // Not palindrome
        return false;
    }
}

【讨论】:

    【解决方案3】:

    您将在第一个字符之后立即返回,因此剩余的任何时候都不会比较

    if (tolower(str[i]) == tolower(str[n-j-1]))
        return true;
    else
        return false;
    

    只有有差异才返回,否则等到所有字符都比较完

    【讨论】:

      【解决方案4】:

      如果您使用的是 C++,则使用 vector。先将字符串插入一个向量,将向量反转然后检查原向量与反转向量是否相等。如果相等,则回文,否则不相等。

      您不需要任何指针。简单的。 :)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 2023-03-22
        • 2018-03-24
        • 2012-04-24
        • 2015-05-18
        相关资源
        最近更新 更多