c++ - 循环遍历 vector <string>并保留每个元素的 "count"时出现问题

标签 c++ c++11

首先,这是我在网站上的第一个问题。我做了很多研究,我认为我没有发现这样一个具体的问题,但如果我错了,请随时在答案中纠正我并将所述主题链接到我。

就问题本身而言,作业由一个控制台应用程序组成,该应用程序将显示输入的每个不同单词以及每个唯一单词出现的次数。我决定解决这个问题的方法是使用 vector<string>然后使用嵌套循环结构,其中外部循环将表示每个唯一单词内部循环将用于将外部循环中的单词与 vector 中的每个现有单词进行比较

但是。我遇到了一个问题。

通过这个基本设置:

//Sort vector into alphabetical order
sort(words.begin(), words.end()); //this only sorts them alphabetically, but equal strings are "next" to each other

//Find unique values
for(string::size_type i=0; i != words.size(); i++) {
    int count = 0;
    for(string::size_type j=0; j != words.size(); j++) {
        if(words[i] == words[j]){
            count++;
        }
    }
    cout << words[i] << " appeared: " << count << " times." << endl;
}

就功能而言,一切正常;正确发现了单词的 2 个以上实例,但它们作为自己的行显示了 2 次以上,因为每当在外循环中遇到重复元素时,实例就会重复自身。

这是一张图片: Basic Result Promblem, Duplicate Output

我想我可以用以下代码解决它:

//Sort vector into alphabetical order
sort(words.begin(), words.end()); //this only sorts them alphabetically, but equal strings are "next" to each other

//Find unique values
for(string::size_type i=0; i != words.size(); i++) {
    int count = 0;
    for(string::size_type j=0; j != words.size(); j++) {
        if(words[i] == words[j]){
            count++;
            if(i != j){ //replacement: delete duplicate values from the vector (aka if the indexes don't match)
                words.erase(words.begin() + j); //delete element at index "j"
            }
        }
    }
    cout << words[i] << " appeared: " << count << " times." << endl;
}

由此产生了一个新问题:出现 2 次以上的单词现在会引发错误。索引本身可以正常工作,即如果我添加 cout << words[i] << endl;删除元素后,它会立即显示正确的单词。但是,出现 2 次以上的单词根本不显示,并返回错误。

这是一张图片:Updated problem, now duplicate values throw an error

任何人都可以解释为什么会发生这种情况以及如何解决它吗?

最佳答案

让我们看看您的示例案例失败的地方:

for(string::size_type j=0; j != words.size(); j++) { // i: 1, j: 2, size(words): 3
    if(words[i] == words[j]){ // words[i] matches words[j]
        count++;
        if(i != j){ // i doesn't match j
            words.erase(words.begin() + j); // i: 1, j: 2, size(words): 2
        }
    }
} // Upon rexecuting the iteration expression i: 1, j: 3, size(words): 2 thus `j` will be greater than `size(words)` and will be used to continue the loop even though it is an invalid index

已经提出了多种解决方案来使用您当前的代码解决此问题。但我建议解决这个问题的最简单方法是 multiset :

const multiset<string> words{istream_iterator<string>(cin), istream_iterator<string>()};
auto it = cbegin(words);

while(it != cend(words)) {
    auto i = words.upper_bound(*it);

    cout << *it << " appeared: " << distance(it, i) << " times\n";
    it = i;
}

您可以在此处查看一个实例:http://ideone.com/Nhicos请注意,此代码不需要输入序列终止字(在您的情况下为“-end”),而是依赖于 EOF。它会自动附加到 http://ideone.com输入:Read cin till EOF

关于c++ - 循环遍历 vector <string>并保留每个元素的 "count"时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44060402/

相关文章:

c++ - 从循环中提升动态类型(也就是以 C++ 方式执行 Java)

c++ - 未调用重载的赋值运算符

c++ - decltype 和 boost::variant - 检索当前值

c++ - 重用 move 的容器?

c++ - 如何使用右值在 C++11 中复制或别名对象?

c++ - 将动态二维数组在 C++ 和 Fortran 之间传递

python - 是什么导致我的 Python C 扩展崩溃?

C++,set_terminate 是每个线程的本地吗?

c++ - 如何从 std::string 转换为模板化 T,或者先检查是否可行?

c++ - 跨 DLL 边界访问虚拟方法是否安全/可能?