当我比较两个向量中的元素时出错 - 我做错了吗?

时间:2016-03-19 12:40:31

标签: c++ vector

任务非常简单:创建一个程序,告诉用户他或她输入的句子是否向后和向前相同(根据使用的单词,而不是拼写)。例如,"I am that am I"(请忽略这可能是语法无意义的)。所以我决定创建两个字符串向量 - 一个用于存储原始句子,另一个用于反转句子。每个向量的元素都是包含句子单词的字符串,例如["I", "am", "that", "am", I"],不包括字符串中的任何空格。

我陷入了解决这个问题的初步状态 - 比较这两个向量的元素。这是我下面的代码(请注意,句子是第一个向量,reverseString是第二个向量,包含相反顺序的元素):

        for (int i = 0; i < sentence.size(); i++) {
            // The below output is for debugging purposes
            cout << "The index is " << i
                 << " and the original string at this location is " << sentence[i]
                 << " and the reverse string is " << reverseString[i] << endl;

            if (sentence[i] == reverseString[i]) {
                cout << reverseString[i] << "---" << sentence[i] <<  endl;
                cout << "A match!" << endl;
            } else {
                cout << reverseString[i] << "---" << sentence[i] << endl;
                cout << "Not a match!" << endl;
            }
        }

奇怪的是,上面的代码似乎可以准确地处理索引1到vector.size()-2中的元素(请记住,c ++的向量中的索引开始为零)。但索引0或vector.size()-1 - 即每个向量的第一个和最后一个元素 - 总是产生"Not a match!",无论句子是什么。两者之间的所有内容都是准确比较的,但这两个位置都不是。

这是一个非常奇怪的错误。也许我的错误在于创建第二个向量?这是我使用的代码:

    int t = sentence.size() - 1;
    for (int i = 0; i < sentence.size(); i++) {
        reverseString[i] = sentence[t];
        t--;
    }

我无意中改变了一些我不应该为第一个和最后一个元素做出改变的东西,这是我能够看到的一种方式吗?我的逻辑有缺陷吗?请让我知道你的想法:)

编辑:我发布了以下代码的最小,完整且可验证的示例

#include <iostream>
#include <vector>
#include <sstream>

using namespace std;

int main() {
    string input;
    cout << "Please input a sentence - no preceding or trailing spaces."
            " It will be analyzed accordingly: ";

    getline(cin, input);

    string secondString = "";
    secondString[0] = input[0];

    int i = 0; 
    for (i = 0; i <= input.length(); i++) {
        // the below strips a string of punctuation if there is any, 
        // as these characters would mess up the comparison.

        if (input[i] == ',' || input[i] == ';' || input[i] == ':' ||
            input[i] == '.' || input[i] == '?' || input[i] == '!') {
        } else {
            secondString = secondString + input[i];
        }
    }

    // now stuff the individual words in the string into a vector
    vector<string> sentence;

    // now we are going to stuff each word into a vector
    string word;
    stringstream ss(secondString);

    while (getline(ss, word, ' ')) {
        sentence.push_back(word);
    }

    // now for Task 1 - we will create a second vector that is reversed.
    // Then compare both vectors - if identical, note it. 

    vector<string> reverseString;
    reverseString = sentence; 

    int t = sentence.size() - 1;
    for (int i = 0; i < sentence.size(); i++) {
        reverseString[i] = sentence[t];
        t--;
    }

    for (int i = 0; i < sentence.size(); i++) {
        cout << "The index is " << i
             << " and the original string at this location is " << sentence[i]
             << " and the reverse string is " << reverseString[i] << endl;

        if (sentence[i] == reverseString[i]) {
            cout << reverseString[i] << "---" << sentence[i] <<  endl;
            cout << "A match!" << endl;
        } else {
            cout << reverseString[i] << "---" << sentence[i] << endl;
            cout << "Not a match!" << endl;
        }
    }
    return 0;
}

2 个答案:

答案 0 :(得分:3)

由于此行中的比较,您有未定义的行为

for (i = 0; i <= input.length(); i++)

input[i]等于i时,循环体尝试访问input.length()时,会发生未定义的行为。成功:

for (i = 0; i < input.length(); i++)

程序没有崩溃只是运气不好,或者你可能早先发现错误。

当我尝试它时发生的事情是,secondString附加了一个多余的空格字符,最终导致sentence中的最后一个元素在末尾有一个额外的空格,所以第一个最后的话永远不会平等。

另请注意,句子比较代码本身过于复杂,因为您可以通过std::equal获得std::vector#include <vector> #include <string> #include <algorithm> #include <iostream> bool compare(std::vector<std::string> const& sentence) { // returns true if the range from the first to the middle element // is equal to the range from the last to the middle element return std::equal( sentence.begin(), sentence.begin() + sentence.size() / 2, sentence.rbegin() ); } int main() { std::vector<std::string> const sentence1 = { "I", "am", "that", "am", "I" }; std::vector<std::string> const sentence2 = { "am", "that", "am", "I" }; std::vector<std::string> const sentence3 = { }; std::vector<std::string> const sentence4 = { "I", "am", "that", "that", "am", "I" }; std::vector<std::string> const sentence5 = { "I" }; std::cout << compare(sentence1) << "\n"; // true std::cout << compare(sentence2) << "\n"; // false std::cout << compare(sentence3) << "\n"; // true std::cout << compare(sentence4) << "\n"; // true std::cout << compare(sentence5) << "\n"; // true } 的反向迭代器,以更简单的方式实现目标}成员函数,并将范围分成两半,如下例所示:

std::vector

此解决方案只需要一个for (int i = 0; i < sentence.size(); i++) { ,并且不会执行比必要更多的比较;当达到句子的中间元素时,结果已经知道。

相比之下,您的原始代码不必要地迭代整个句子:

/

答案 1 :(得分:1)

  

首先,secondString [0] = input [0];当secondString时无效   是空的。同样地(i = 0; i&lt; = input.length();应该在之前停止   到达input.length()。 - Bo Persson 12分钟前

Bo Persson的评论解决了您的问题。