在列表中找到最常见的元素(C STL)

Finding most common element in a list (C++ STL)?

本文关键字:元素 STL 常见 列表      更新时间:2023-10-16

我有一个程序,我必须在整数列表中找到最常见的元素。我在下面的程序中做到这一点,但是问题是,我怀疑擦除功能会随着countRepetition()函数中的迭代器增量而混乱。我的问题是我该如何解决问题,或者如果不是问题是什么?

预先感谢。

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

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中有一个无效的迭代器。您将STARTmain传递到countRepetition,当该迭代器从列表中删除时,您就会有一个无效的迭代器。您需要做的是从列表中获取新的begin迭代器,因为您总是删除第一个元素。那会使您的循环看起来像

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

另一个问题是您只检查字符是否不是0。如果您要计算重复,则需要确保检查迭代器是否是相同的字符。我将留下来供您实施。


我还想指出,有一种更简单的方法可以完成所有这些操作。std::map使您可以很容易地构建直方图。将其与std::max_element相结合,您可以将整个程序编写为

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

您的问题是您在各地使用全局变量。全局启动在两个循环中更改,因此您仅访问第一个循环一次,然后在第二个函数中再次更改,并且您不会第二次执行第一个循环。

为什么使用全局变量?您不应该使用它们,而应使用本地变量。

这可能是您要寻找的:

#include <iostream>
#include <list>
#include <vector>
#include <map>
using namespace std;
list <char> l;
map<char, int> ans;
int main()
{
    char c;
   do{
       c = getchar();
       l.push_back(c);
   }while(c != '0');
   for(auto chr: l){
       ans[chr]++;
   }
   char ch;
   int mx = 0;
   for(auto k: ans){
       if(k.second > mx)
       {
           ch = k.first;
           mx = k.second;
       }
   }
   cout<<ch<<" : "<<mx;
}