检查一个字符串是否是回文字符串

17

我需要创建一个程序,允许用户输入一个字符串,然后我的程序将检查该字符串是否为回文(可以正反读取的单词)。


2
我首先会点击右上角的小“搜索”栏,输入“回文”,然后浏览各种语言中数十个可能的答案。 - Mike Christensen
4
@MikeChristensen 这是一个标记为 C 的问题,当辩论答案时人们抱怨的事情在 C++ 中可能会有所不同... - HostileFork says dont trust SE
如果您需要检查整数向量是否为回文:链接 - xinthose
8个回答

78

请注意,完全颠倒字符串(使用 rbegin()/rend() 范围构造函数或 std::reverse 函数)并将其与输入进行比较将执行不必要的工作。

只需将字符串的前半部分与后半部分相反地进行比较即可:

#include <string>
#include <algorithm>
#include <iostream>
int main()
{
    std::string s;
    std::cin >> s;
    if( equal(s.begin(), s.begin() + s.size()/2, s.rbegin()) )
        std::cout << "is a palindrome.\n";
    else
        std::cout << "is NOT a palindrome.\n";
}

演示:http://ideone.com/mq8qK


4
+1 在资源和时间复杂度方面绝对更优。 - sehe

56

只需将字符串与其反转后的形式进行比较:

string input;

cout << "Please enter a string: ";
cin >> input;

if (input == string(input.rbegin(), input.rend())) {
    cout << input << " is a palindrome";
}

这个 string 构造函数接受一个起始和结束迭代器,从这两个迭代器之间的字符创建字符串。由于 rbegin() 是字符串的结尾,并且将其递增会向后遍历字符串,所以我们创建的字符串将倒序添加 input 的字符,即翻转字符串。

然后,只需将它与 input 进行比较,如果它们相等,则是回文。

这不考虑大小写或空格,因此你需要自己进行改进。


3
我本来想给你的回答点赞的,但有一个明显的抱怨:这是作业,请提供一种方法/算法,而不是代码。这个练习让 OP 学到了什么?懒惰是要付出代价的。:( - Nim
当字符串具有奇数个字符时,它无法正常工作。 - Iti Shree

12
bool IsPalindrome(const char* psz)
{
    int i = 0;
    int j;

    if ((psz == NULL) || (psz[0] == '\0'))
    {
        return false;
    }

    j = strlen(psz) - 1;
    while (i < j)
    {
        if (psz[i] != psz[j])
        {
            return false;
        }
        i++;
        j--;
    }
    return true;

}

// STL字符串版本:

bool IsPalindrome(const string& str)
{
    if (str.empty())
        return false;

    int i = 0;                // first characters
    int j = str.length() - 1; // last character

    while (i < j)
    {
        if (str[i] != str[j])
        {
            return false;
        }
        i++;
        j--;
    }
    return true;
}

6
抱歉,这个问题标记为C++,而且在这种情况下,没有理由产生这样的混淆代码(永远不会有)。请参考Cubbi的答案以立即证明。 - sehe
9
你真的认为上面的代码是混淆的吗?Cubbi的解决方案只是STL的高级技巧,没有任何问题。但上面的代码是问题的经典解决方案——只是没有使用STL。为了让你满意,我会展示一个合理的STL变体来解决同样的问题。 - selbie
诚然,情况可能会更糟。如果您使用C++(不一定是STL)的变体,让我去掉我的-1。 - sehe
1
我不知道你所说的“C++”变体是什么,它不是STL。几乎所有的C代码都是有效的C++代码。当有人在C/C++中谈到“字符串”时,我想到的是“字符指针”。 “字符串类”只是一个char指针的封装,带有额外的开销和一些巧妙的功能。我花了比我愿意承认的更多年的时间来努力使我编写的所有代码行可读、可理解和可维护。所以你可以看出为什么我的代码被称为“混淆”的时候我会感到很激动。 - selbie
3
你编写的代码是C++,而不是STL。使用STL意味着使用STL功能,如迭代器和算法。你没有使用任何这些功能。C++的特点在于字符串是具有受控生命周期和分配的一等对象。此外,字符串可以轻松包含空字符。我的观点是:即使你不喜欢STL,使用C++风格的好处已经非常显著了;因此,没有理由使用char*strlen(因为它们更容易出错且不够灵活)。 - sehe
显示剩余6条评论

1
// The below C++ function checks for a palindrome and 
// returns true if it is a palindrome and returns false otherwise

bool checkPalindrome ( string s )
{
    // This calculates the length of the string

    int n = s.length();

    // the for loop iterates until the first half of the string
    // and checks first element with the last element,
    // second element with second last element and so on.
    // if those two characters are not same, hence we return false because
    // this string is not a palindrome 

    for ( int i = 0; i <= n/2; i++ ) 
    {
        if ( s[i] != s[n-1-i] )
            return false;
    }
    
    // if the above for loop executes completely , 
    // this implies that the string is palindrome, 
    // hence we return true and exit

    return true;
}

3
如果你在代码中添加一些注释或解释,这样会更好,但是请确保不改变原本的意思,同时保证内容容易理解。 - Pat. ANDRIA
1
虽然这段代码可以回答问题,但是提供关于为什么和/或如何回答问题的额外背景信息会增加它的长期价值。 - Donald Duck
好的,这是我在StackOverflow上的第一个答案。我现在一定会添加注释。 - mahaturbotorque

0

从两端开始检查字符串并在中间相遇。如果存在差异,则返回false。

#include <iostream>

bool palidromeCheck(std::string str) {
    for (int i = 0, j = str.length()-1; i <= j; i++, j--)
        if (str[i] != str[j])
            return false;
    return true;
}

int main(){
    std::cout << palidromeCheck("mike");
    std::cout << palidromeCheck("racecar");
}

0
#include <iostream>
#include <string>

bool isPalindrome(const std::string& str){

    if(str.empty()) return true;

    std::string::const_iterator itFirst = str.begin();
    std::string::const_iterator itLast = str.end() - 1;

    while(itFirst < itLast) {
        if (*itFirst != *itLast)
            return false;
    
        ++itFirst;
        --itLast;
    }
    return true;
}

int main(){

    while(1){
        std::string input;
        std::cout << "Eneter a string ...\n";
        std::cin >> input;

        if(isPalindrome(input)){
            std::cout << input <<  " is palindrome.\n";
        } else {
            std::cout << input << " is not palindrome.\n";
        }
    }

    return 0;
}

-3

将字符串反转并检查原始字符串和反转后的字符串是否相同


-12
我不是C++专家,但你应该能够从中理解要点。
public static string Reverse(string s) {
    if (s == null || s.Length < 2) {
        return s;
    }

    int length = s.Length;
    int loop = (length >> 1) + 1;
    int j;
    char[] chars = new char[length];
    for (int i = 0; i < loop; i++) {
        j = length - i - 1;
        chars[i] = s[j];
        chars[j] = s[i];
    }
    return new string(chars);
}

23
如果您不是C++专家,并且使用 pidgin C++ 回答一个无法编译的C++问题,那么为什么要这样做呢?如果在不熟悉的语言中提供建议,我的建议是使用“明显”的伪代码,它几乎像英语。(例如,Let L = Length of Sint length = s.Length更不容易让人翻白眼) - HostileFork says dont trust SE
任何熟悉编程的人都应该能够弄清楚它。哎呀,我想"敌对的"是适合形容你的修饰语。 - varatis
7
我会尽力进行翻译。这段话的意思是:“我只注意到在大约30秒后,它甚至没有检查回文。所以,它是混淆的,并且不是一个答案?”请注意,我不能提供任何解释或添加额外的信息。 - sehe
3
我认为我的回答很适当,我没有给你投反对票(有人投了反对票,但是他们可能解释或者没有解释)。我提出了一个建议,告诉你如何在这种情况下提供反馈,而不需要编写不能编译的代码,这样很可能会让新手C++程序员更加困惑。至于什么是软件开发中的敌对分支,请自行查阅。 - HostileFork says dont trust SE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接