【问题标题】:c++ how to print how many times each integer appears in the STL listc ++如何打印每个整数在STL列表中出现的次数
【发布时间】:2018-06-25 17:17:09
【问题描述】:
using namespace std;

int main()
{
    list<int> numbers; list<int> numb;

    for (int i = 0; i<10; i++)
        numbers.push_back(rand() % 20);

    list<int>::iterator it;

    for (it = numbers.begin(); it != numbers.end(); ++it)
    {
        cout << *it << " ";
    }

    return 0;
}

我想使用std::count(),但我无法正确使用。我尝试执行以下操作:

using namespace std;

int main()
{
    list<int> numbers; list<int> numb;

    for (int i = 0; i<10; i++)
        numbers.push_back(rand() % 20);

    list<int>::iterator it;

    for (it = numbers.begin(); it != numbers.end(); ++it)
    {
        cout << *it << " ";

        while (it != numbers.begin() && it != numbers.end())
        {
            ++it;
            *it = count(it, numbers.begin(), numbers.end());
            cout << " " << *it;
        }

        cout << endl;
    }

    return 0;
}

但它给了我一个错误:

二进制 == 未找到采用左手运算符类型“int”的运算符(或没有可接受的转换)。

我知道我做错了什么。

我还尝试了一些其他方法,例如int numb = std::count(numbers.begin()), numbers.end(), *it),但也没有成功。所以,我想知道是否有一个特殊的运算符来计算列表中的值。

【问题讨论】:

  • 1) 你读过std::count的文档吗?提示:有示例部分。 2)“_我还尝试了一些其他的东西<...>,但也没有用_”请解释一下如何没用。这样的陈述,就其本身而言,对读者没有任何用处。

标签: c++ list count stl operators


【解决方案1】:

您需要再次查看std::count 的签名。它接受三个参数std::count(InputIterator first, InputIterator last, const T&amp; val);,并返回数据集中val 的出现次数。所以这样的事情应该对你有用,theNumber 是你正在计算的数字。

#include <algorithm>

int occurrences = std::count(numbers.begin(), numbers.end(), theNumber); 

【讨论】:

    【解决方案2】:

    您没有正确使用迭代器(您正在修改it,而您仍在使用它来迭代列表),并且您没有正确调用std::count()

    代码应该看起来更像这样:

    #include <iostream>
    #include <list>
    #include <algorithm>
    #include <cstdlib>
    
    int main()
    {
        std::list<int> numbers;
        int numb;
    
        for (int i = 0; i < 10; i++)
            numbers.push_back(std::rand() % 20);
    
        std::list<int>::iterator it;    
    
        for (it = numbers.begin(); it != numbers.end(); ++it)
        {
            numb = std::count(numbers.begin(), numbers.end(), *it);
            std::cout << *it << " " << numb << std::endl;
        }
    
        /* or:
        for (int value : numbers)
        {
            numb = std::count(numbers.begin(), numbers.end(), value);
            std::cout << value << " " << numb << std::endl;
        }
        */
    
        return 0;
    }
    

    但是,就像其他人说的那样,您应该使用std::map 来跟踪计数,这样您就可以考虑重复,例如:

    #include <iostream>
    #include <list>
    #include <map>
    #include <cstdlib>
    
    int main()
    {
        std::list<int> numbers;
        std::map<int, int> numb;
    
        for (int i = 0; i < 10; i++)
            numbers.push_back(rand() % 20);
    
        for (std::list<int>::iterator it = numbers.begin(); it != numbers.end(); ++it)
            numb[*it]++;
    
        /* or:
        for (int value : numbers)
            numb[value]++;
        */
    
        for (std::map<int, int>::iterator it = numb.begin(); it != numb.end(); ++it)
            std::cout << it->first << " " << it->second << std::endl;
    
        /* or:
        for (auto &item : numb)
            std::cout << item.first << " " << item.second << std::endl;
        */
    
        return 0;
    }
    

    可以简化为:

    #include <iostream>
    #include <map>
    #include <cstdlib>
    
    int main()
    {
        std::map<int, int> numb;
    
        for (int i = 0; i < 10; i++)
            numb[rand() % 20]++;
    
        for (std::map<int, int>::iterator it = numb.begin(); it != numb.end(); ++it)
            std::cout << it->first << " " << it->second << std::endl;
    
        /* or:
        for (auto &item : numb)
            std::cout << item.first << " " << item.second << std::endl;
        */
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      一般来说,使用地图是解决问题的更好方法,但如果您必须使用列表来解决问题,这是一种可能的解决方案:

      #include <iostream>
      #include <algorithm>
      #include <list>
      
      int main()
      {
          std::list<int> numbers, unique_num, numb;
          int num;
      
          // Create both the original list and a list that
          // will be left with only unique numbers
          for (int i = 0; i<10; i++){
              num = rand() % 20;
              numbers.push_back(num);
              unique_num.push_back(num);
          }
      
          // Sort and select the unique numbers
          unique_num.sort();
          unique_num.unique();
      
          // Count unique numbers and store the count in numb
          std::list<int>::iterator iter = unique_num.begin();
          while (iter != unique_num.end())
              numb.push_back(count(numbers.begin(), numbers.end(), *iter++));
      
          // Print the results
          for(std::list<int>::iterator iter1 = unique_num.begin(), iter2 = numb.begin();
                  iter2 != numb.end(); iter1++, iter2++)
              std::cout<< "Number " << *iter1 << " appears " <<
                *iter2 << ( *iter2 > 1 ? " times " : " time" ) << std::endl;
      
          return 0;
      }
      

      程序使用另一个列表unique_num 来保存出现在numbers 中的唯一编号。该列表最初创建时与numbers 相同,然后进行排序并删除重复项。

      然后程序会遍历该唯一列表中的数字,并使用 count 来获取每个数字在原始 numbers 列表中出现的次数。然后将出现次数存储在一个新列表numb 中。

      打印时,程序使用三元运算符来检查是否应该打印“time”或“times”,具体取决于结果是否意味着出现一次或多次。

      注意 - 如果您每次运行程序时都需要不同的列表值,您需要使用 srand 更改随机种子。在你的程序中包含标题 #include &lt;time.h&gt; 和在你的 main 开头的行 srand(time(NULL));

      【讨论】:

      • 非常感谢,这非常有效。一个问题,numbers.push_back(rand() % 20 和 num = rand() % 20; numbers.push_back(num) 有什么区别???
      • 很高兴为您提供帮助 :) 不过,您是否已经覆盖了地图?这是为了上课吗?因为真正的地图解决方案是您将来可能想要做的。在当前版本中,由于程序将相同的随机数添加到两个列表中,它首先生成数字 (num),然后将其添加到列表中。否则它将分配不同的数字。我将添加一件与 rand 相关的重要内容。
      • 是的,这是给我的 c++ 课的,我们还没有介绍地图,但我们下周会介绍。我非常感谢您的建议,它们确实帮助我更好地理解了这个项目。我会检查你关于兰德的信息。
      • 如果您对此代码有任何疑问,请在评论中提问,我会在答案中澄清。读完之后,试一试有无 srand,你会看到 :)
      • 请注意,尽管很方便,using namespace std; 被认为是一种不好的做法,因为它在命名空间中散布着数百个不需要的符号。使用using std::list; using std::cout;(等),如果需要太多,可以放在单独的头文件中。
      【解决方案4】:

      我建议你使用地图:

      map<int, int> counts;
      for(int val : Numbers)
        ++counts[val];
      

      【讨论】:

        【解决方案5】:

        带额外内存:

        您可以使用存储桶来获得 O(N + MAX_NUM) 的复杂度。所以当 MAX_NUM

        #include <iostream>
        #include <list>
        #include <algorithm>
        #include <ctime>
        
        const int MAX_NUM = 20;
        const int N = 10;
        
        int main() {
            std::list<int> numbers;
            int buckets[MAX_NUM];
        
            std::fill(buckets, buckets + MAX_NUM, 0);
        
            srand(time(NULL));
        
            for (int i = 0; i < N; i++) numbers.push_back(rand() % MAX_NUM);
        
            // computing
            for (auto it = numbers.begin(); it != numbers.end(); ++it) {
                buckets[*it]++;
            }
        
            //printing answers
            for (int i = 0; i < MAX_NUM; i++) {
                if (buckets[i]) std::cout << "value " << i << " appears in the list " << buckets[i] << " times." <<std::endl;
            }
        
            return 0;
        }
        

        对于大数据,我建议将 std::unordered_map 用于存储桶,然后获得 O(N) 复杂度(感谢散列):

        #include <iostream>
        #include <list>
        #include <algorithm>
        #include <ctime>
        #include <unordered_map>
        
        const int N = 10;
        const int MAX_NUM = 20;
        int main() {
            std::list<int> numbers;
            std::unordered_map<int, int> buckets;
        
            srand(time(NULL));
        
            for (int i = 0; i < N; i++) numbers.push_back(rand() % MAX_NUM);
        
            // computing
            for (auto it = numbers.begin(); it != numbers.end(); ++it) {
                buckets[*it]++;
            }
        
            //printing answers
            for (auto & k_v : buckets) {
                std::cout << "value " << k_v.first << " appears in the list " << k_v.second << " times." <<std::endl;
            }
            return 0;
        }
        

        无需额外内存:

        以更通用的方式,您可以使用 std::vector 代替 std::list 和 std::sort ,然后在简单的 for 中计算值的变化。复杂度为 O(N log N):

        #include <iostream>
        #include <vector>
        #include <algorithm>
        #include <ctime>
        
        const int N = 10;
        const int MAX_NUM = 20;
        
        int main() {
            std::vector<int> numbers;
        
            srand(time(NULL));
        
            for (int i = 0; i < N; i++) numbers.push_back(rand() % MAX_NUM);
        
            // sorting
            std::sort(numbers.begin(), numbers.end());
        
            //printing answers for sorted vector
            if (numbers.size() > 0) {
                int act_count = 1;
                for (int i = 1; i < numbers.size(); i++) {
                    if (numbers[i] != numbers[i -1]) {
                        std::cout << "value " << numbers[i-1] << " appears in the list " << act_count << " times." <<std::endl;
                        act_count = 1;
                    } else {
                        act_count++;
                    }
                }
                std::cout << "value " << numbers[numbers.size() - 1] << " appears in the list " << act_count << " times." <<std::endl;
            }
            return 0;
        }
        

        你也可以在std::list上做上面的,也得到O(nlogn),但是不能使用std::sort:

        #include <iostream>
        #include <list>
        #include <ctime>
        
        const int N = 10;
        const int MAX_NUM = 20;
        
        int main() {
            std::list<int> numbers;
        
            srand(time(NULL));
        
            for (int i = 0; i < N; i++) numbers.push_back(rand() % MAX_NUM);
        
            // sorting
            numbers.sort();
        
            //printing answers for sorted list
            if (!numbers.empty()) {
                int act_count = 0;
                auto prev = numbers.begin();
                for (auto it = numbers.begin(); it != numbers.end(); it++) {
                    if (*it != *prev) {
                        std::cout << "value " << *it << " appears in the list " << act_count << " times." <<std::endl;
                        act_count = 1;
                    } else {
                        act_count++;
                    }
                    prev = it;
                }
                std::cout << "value " << *prev << " appears in the list " << act_count << " times." <<std::endl;
            }
        
            return 0;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多