1

今天是个好日子!下面是一个程序,它询问用户一个句子并输出其中的回文数。

#include<iostream>
#include<string>
#include<sstream>

using namespace std;

bool isPalindrome (const std::string& s) {
    for (int i = 0; i < (s.length())/2; ++i) {
        if (s[i] != s[s.length()-1 - i])
            return false;
        else
            return true;
    }
}


int main() {
    string sentence;
    int counter=0;
    cout << "Please input a sentence." << endl;
    getline(cin, sentence);
    stringstream processtokens(sentence);
    for(string word; processtokens >> word;) 
        if(isPalindrome(word)) 
            ++counter;
    cout << "Number of Palindromes are : " << counter << endl;
}

它工作得很好。但是例如,当我输入“The quick brown gag has a blue eye.”时,程序显示的回文数只有 1,但实际上,该句子有 2 个回文:gag 和 eye。问题是“眼睛”这个词有句号。那么当用户输入“我喜欢中午、晚上和午夜”时,程序如何忽略句点和逗号等其他标点符号。Noon 是回文,但由于逗号,程序无法识别它。

另一个问题是大小写。当用户输入“女士,我的工作已完成”时,我希望该程序能够工作(并忽略 ASCII 等效项)。我知道这与tolow有关。

总而言之,我希望该程序具有以下功能:a)忽略标点符号和 b)大写

哦,“stringstream processtokens(sentence);...”的替代方法是什么?相反,我需要这个程序来使用substring (substr) 和 find

请指导我,伙计们!谢谢您,非常感谢您提供任何帮助。再次感谢,祝您有美好的一天!

4

3 回答 3

2

您可以使用ispunct并忽略任何 ispunct 返回 true 的字符。您还应该在调用tolower ()中包装您的字符比较

于 2012-01-25T06:03:55.837 回答
2

也许这个小练习可以用来介绍一些不错的 C++ 特性,例如迭代器:

inline bool is_letter(char c)
{ return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); }


bool is_palindrome(const std::string & s)
{
    std::string::const_iterator it = s.begin();
    std::string::const_reverse_iterator rt = s.rbegin();

    while (it != s.end() && rt != s.rend() && std::distance(it, rt.base()) > 0)
    {
        // Skip non-letters
        while (it != s.end() && !is_letter(*it)) { ++it; }
        while (rt != s.rend() && !is_letter(*rt)) { ++rt; }

        if (it == s.end() || rt == s.rend()) { break; }

        // Check palindromy
        if (std::tolower(*it) != std::tolower(*rt)) { return false; }

        // Move on
        ++it;
        ++rt;
    }

    return true;
}

诀窍是从两端攻击字符串。为此,我们有一个it来自字符串开头的普通迭代器 ,和一个来自字符串结尾的反向迭代器rt

代码的核心是检查回文(不区分大小写,通过比较小写字符),并且return false在失败时立即检查;否则,两个迭代器将提前一个。

最后,循环的开头从字符串中吞噬了非字母字符,因此完全忽略了这些字符。我们再次检查是否在 gobbling 后到达了字符串的末尾;您必须确保仅将迭代器取消引用到有效元素!

当向前移动的迭代器经过向后移动的迭代器时,循环停止。这是条件的内容distance(it, rt.base()) > 0:反向迭代器的“基”实际上是反向迭代器元素之后的元素的普通迭代器。所以只要从到 的底边的距离严格大于零,it就不会越过。(当和引用同一个元素时,距离正好为 1。)rtitrtitrt

于 2012-01-25T06:34:45.857 回答
0

我认为有一个检查标点符号的功能。你可能想试试ispunct

于 2012-01-25T05:59:24.683 回答