c++ - 比较两个 vector 中的元素时出现错误 - 我做错了什么吗?

标签 c++ vector

任务非常简单:创建一个程序,告诉用户他或她输入的句子前后是否相同(根据使用的单词,而不是拼写)。例如,"I am that am I"(请忽略这在语法上的荒谬程度)。所以我决定创建两个字符串 vector - 一个用于存储原始句子,另一个用于将句子颠倒过来。每个 vector 的元素将是包含句子单词的字符串,例如 ["I", "am", "that", "am", I"],不包括字符串中的任何空格.

我停留在解决这个问题的初步状态 - 比较这两个 vector 的元素。下面是我的代码(注意 sentence 是第一个 vector ,reverseString 是第二个 vector ,包含倒序的元素):

        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++ 的 vector 中的索引从零开始)。但是索引 0 或 vector.size()-1 - 即每个 vector 的第一个和最后一个元素 - 总是产生一个 “不匹配!”,无论句子。两者之间的所有内容都经过准确比较,但那两个位置没有。

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

    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;
}

最佳答案

由于这一行中的比较,您有未定义的行为:

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

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

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

程序没有崩溃只是运气不好,否则你可能早就注意到了这个错误。

我尝试时发生的事情是,一个多余的空格字符附加到 secondString,这最终导致 sentence 中的最后一个元素在结束,所以第一个词和最后一个词永远不会相等。


另请注意,句子比较代码本身太复杂了,因为您可以使用 std::equal 以更简单的方式实现您的目标。 , std::vectorrbegin() 获得的反向迭代器成员函数,并将范围分成两半,如本例所示:

#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++) {

关于c++ - 比较两个 vector 中的元素时出现错误 - 我做错了什么吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36101865/

相关文章:

c++ - vector 类型值不匹配错误

c++ - upper_bound 并找到不同的结果

c++ - 访问其对象位于模板类 vector 中的特定子类函数

c++ - 如何在 CMake 中检查 Windows 版本?

c++ - 64 位地址

c++ "class"没有命名类型

C : Vec of structures

c++ - native C++ SQL 框架

c++ - 从 HBITMAP 转换为 IWICBitmap

sorting - C++ std::const 结构的排序