【问题标题】:Finding most common element in a list (C++ STL)?查找列表中最常见的元素(C++ STL)?
【发布时间】:2018-09-11 18:54:40
【问题描述】:

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

提前致谢。

【问题讨论】:

    标签: c++ list vector stl iterator


    【解决方案1】:

    您有几个问题。首先,正如您所怀疑的那样,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 循环看起来像

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

    【讨论】:

      【解决方案2】:

      这可能是您正在寻找的:

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

      【讨论】:

        【解决方案3】:

        你的问题是你到处都使用全局变量。 全局 START 在两个循环中更改,因此您只访问第一个循环一次,然后在第二个函数中再次更改它,您不会再次执行第一个循环。

        为什么要使用全局变量?你不应该使用它们,而应该使用局部变量。

        【讨论】:

        • countRepetitionSTART是函数局部变量,不是全局变量。
        猜你喜欢
        • 2018-09-27
        • 2010-12-03
        • 1970-01-01
        • 2017-06-14
        • 2012-07-06
        相关资源
        最近更新 更多