查找列表中最常见的元素(C ++ STL)? [英] Finding most common element in a list (C++ STL)?

查看:204
本文介绍了查找列表中最常见的元素(C ++ STL)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,我必须在整数列表中找到最常见的元素。我使用下面的程序执行此操作,但问题是,我怀疑擦除函数与 countRepetition()函数中的迭代器增量混淆。我的问题是如何解决问题或者这不是问题是什么?

I have a program where I have to find the most common element in a list of integers. I do this with the program below, but the problem is, I suspect that the erase function messes up with the iterator incrementation in the countRepetition() function. My question is how can I fix the problem or if this is not the issue what is it?

提前致谢。

推荐答案

你有几个问题。首先,正如您所怀疑的那样,错误地使用了 erase 。擦除迭代器时,它会使迭代器无效。之后对迭代器的任何使用都是未定义的行为。由于 erase 返回下一个有效的迭代器,你可以做的是重构循环,如

You have a couple issues. First, as you suspected, was the incorrect use of erase. When you erase an iterator it invalidates the iterator. Any use of the iterator afterwards is undefined behavior. Since erase returns the next valid iterator what you can do is restructure the loop like

for (START = l.begin(); START != l.end();) { // do not increment here
    if (*START) {
        counter++;
        START = l.erase(START); // erase and get next
    }
    else
    {
        ++START; // go to next
    }
}

所以现在至少你循环通过清单。不幸的是,你仍然会在 main 中有一个无效的迭代器。您将 START main 传递到 countRepetition 以及该迭代器从列表中删除,然后你有一个无效的迭代器。你需要做的是每次迭代从列表中获取一个新的 begin 迭代器,因为你总是擦除第一个元素。这将使你的for循环看起来像

So now at least you loop through the list. Unfortunately you will still have an invalid iterator in main. You pass START from main to countRepetition and when that iterator is erased from the list you then have an invalid iterator. What you need to do is get a new begin iterator from the list each iteration since you are always erasing the first element. That would make your for loop look like

for (START = l.begin(); START != l.end(); START = l.begin()) {
    m.push_back(countRepetition(START));
}






另一个问题是你刚才检查字符是否不是 0 。如果要计算重复次数,则需要确保检查迭代器是否为相同的字符。我会留给你实施。


Another issue is you just check if the character is not 0. If you are counting repetitions you need to make sure you are checking that the iterator is the same character. I'll leave that for you to implement.

我还想指出有一种更简单的方法所有这些。使用 std :: map 可以非常轻松地构建直方图。将它与 std :: max_element 结合使用,您可以将整个程序编写为

I would also like to point out there is an easier way to do all of this. A std::map lets you build a histogram very easily. Combine that with std::max_element and you could write your entire program as

int main()
{
    std::map<char, int> histogram;
    while ('0' != (number = getchar()))
        ++histogram[number]; // add to map, increment count of occurances

    auto most_frequent = *std::max_element(histogram.begin(), 
                                           histogram.end(), 
                                           [](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; }).first;
    std::cout << most_frequent;    
    return 0;
}

这篇关于查找列表中最常见的元素(C ++ STL)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆