c ++如何打印每个整数出现在STL列表中的次数

时间:2018-01-16 22:15:44

标签: c++ list count stl operators

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

但它给了我一个错误:

  

binary ==找不到左侧操作符类型为'int'的操作符(或者没有可接受的转换)。

我知道我做错了什么。

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

5 个答案:

答案 0 :(得分:2)

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

#include <algorithm>

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

答案 1 :(得分: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;
}

答案 2 :(得分:1)

我建议你使用地图:

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

答案 3 :(得分:1)

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

#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中。

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

注意 - 如果每次运行程序时需要不同的列表值,则需要使用srand更改随机种子。在程序中添加标题#include <time.h>,在主程序的开头添加行srand(time(NULL));

答案 4 :(得分:0)

附加内存:

您可以使用存储桶来获得复杂度O(N + MAX_NUM)。因此,当MAX_NUM <= N时,我们有O(N):

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