2016-11-11 134 views
1

我正在学习C++,并且其中一个练习(Accelerated C++)是编写一个发现回文的小程序。比较字符串显示不等于

为此,我创建了一个载有几个单词的向量,然后我遍历这个向量来查找回文。 迭代时,我创建每个单词的副本,将其颠倒过来,然后比较反转的副本是否与原始单词匹配。

using namespace std; 
vector<string> palindrome(vector<string> v){ 
    for(std::vector<string>::iterator iter = v.begin(); iter != v.end(); ++iter){ 
    string reversed_word; 
    for(int i = iter->size(); i >= 0; i--){ 
     reversed_word += (*iter)[i]; 
    } 
    if (!(*iter).compare(reversed_word)){ 
     cout << reversed_word << endl; 
    } 
    cout << reversed_word << endl; 
    cout << *iter << endl; 
    } 
return v 
} 


int main(){ 
    vector<string> dictionnary; 
    dictionnary.push_back("coloc"); 
    dictionnary.push_back("elle"); 
    dictionnary.push_back("php"); 
    dictionnary.push_back("shahs"); 
    dictionnary.push_back("bonjour"); 
    dictionnary.push_back("random"); 

    palindrome(dictionnary); 
    return 0; 
} 

然而,条件!(*iter).compare(reversed_word)好好尝试返回什么预期是回文词。为了检查,我已经显示了单词和相反的单词,并且它们匹配。

缺少什么我在这里?

+0

'iter <= v.end()'很少是正确的。 “结局”从不指向任何事物;它总是无效的。这个习语是'!= v.end()'。 – Potatoswatter

+0

回文没有任何回报。我不认为这会编译。 – stark

+0

@Potatoswatter感谢您指出了这一点,我从一个整数切换到interator后没有改变这一点。我会编辑它 –

回答

3

此循环迭代多少次?

for(int i = (*iter).size(); i >= 0; i--) 

你可能想要size()-1所以它不会超过单词的结尾。

同样,iter <= v.end()很少是正确的。 end从不指向任何东西;它总是无效的。这个成语是!= v.end()

此外,如果该函数没有返回值,则其返回类型应为void

2

变化iter <= v.end();iter != v.end();, 和

for(int i = (*iter).size(); i >= 0; i--){ 

for(int i = (*iter).size() - 1; i >= 0; i--){ 

阅读:Why is "!=" used with iterators?

1

我相信你将在你的第一个环空字符,努力当得到(*iter)[(*iter).size()]

如果pos是等于串长度和字符串是 const限定,该函数返回一个空字符 (“\ 0”)的参考。

你可以尝试:

for(int i = (*iter).size()-1; i >= 0; i--){ 
     reversed_word = reversed_word + (*iter)[i]; 
    } 

std::cout不会表现出这种差异,即使2串是不同的。

3

这样的代码让我难过!即使纠正,它仍然(原谅我的坦率)丑陋,难以阅读。

C++及其标准库的重点在于允许您在相对抽象的层次上工作 - 但大部分内容已经非常接近汇编语言级别。不是使用vector或字符串作为抽象,而是使用单个字符,每次构建反转字符串一个字符,等等。在抽象方面,这仅仅是汇编语言之上的宝贝步骤(并且比大多数汇编程序使用的语法要丑得多)。

所以,让我们坐下来思考你真的在做什么。

您正在服用一个输入向量。你正在处理每一个,并产生一个结果。这就是std::transform所做的,所以这就是你应该在这里使用的。

因此,我们的任务是定义is_palindrome

在这里,我建议试着去思考更高层次的抽象。 std::string有一个带一对迭代器的构造函数。 std::string也支持反向迭代器 - 您可以使用rbegin()rend()将反向迭代器获取到字符串中。

这两件事情之间,我们可以在一个非常简单的步骤,创建一个颠倒的字符串:

std::string reversed(s.rbegin(), s.rend()); 

std::string也重载相关运营商的大多数,所以代码来比较两个字符串可以更可读:return s == reversed;

之后,我认为值得一提的是当编写加速的C++时,有一两件事情是不可能的,但应该在任何甚至接近当前的编译器上。第一个是初始化列表。相反的:

vector<string> dictionnary; 
    dictionnary.push_back("coloc"); 
    dictionnary.push_back("elle"); 
    dictionnary.push_back("php"); 
    dictionnary.push_back("shahs"); 
    dictionnary.push_back("bonjour"); 
    dictionnary.push_back("random"); 

...你现在可以这样写,如:

vector<string> dictionary{ "coloc", "elle", "php", "shahs", "bonjour", "random" }; 

另一个是lambda表达式。而不是定义is_palindrome作为函数(或仿函数),我们可以指定就地表达式:

std::transform(v.begin(), v.end(), 
       results.begin(), 
       [](std::string const &s) { 
        return s == std::string(s.rbegin(), s.rend()); 
       }); 

有大部分程序中只有5行代码 - 并且看不到任何地方(*iter)[i]

+0

“这样的代码让我难过!”我希望人们在开始时不会这样对待你。你有没有想过其他人没有像你那么多的经历?正如我在我的问题中所说的,我正在学习C++,这是第5章所以是的,这个代码并不完美,甚至可能会很糟糕,但是您并不是从写出惊人的代码开始,即使是你。尽管如此,我感谢你的帮助。 –

+0

@GrahamSlick:我有点担心这一点。事实上,在你评论之前,我试着问一下:http://chat.stackoverflow.com/transcript/message/34006932#34006932。我向你保证,这不是对你的攻击,只是希望*改进它的介绍。 –

+0

@GrahamSlick很明显,很遗憾很多人不好写坏书。 –