Подсчет случаев в векторе

Лучше, чем

All = Cash | Check | CreditCard

решение, потому что, если Вы добавляете другой метод позже, скажите:

PayPal = 8 ,

Вы будете уже сделаны с тильдой - все, но иметь для изменения все-строки с другим. Так его менее подверженное ошибкам позже.

отношения

7
задан Cœur 30 April 2017 в 12:57
поделиться

6 ответов

Как насчет использования карты, где ключ - это номер, который вы отслеживаете, а значение - количество вхождений?

Если вам нужно использовать вектор, у вас уже есть это отсортировано. Так что просто следите за номером, который вы видели ранее. Если оно совпадает с текущим числом, увеличьте счетчик. Каждый раз, когда число изменяется: распечатайте текущее число и счетчик, сбросьте счетчик, установите число last_seen на новое число.

6
ответ дан 6 December 2019 в 09:21
поделиться

Вы можете использовать карту чисел для счетчиков:

typedef map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
   CounterMap::iterator it(counts.find(numbers[i]));
   if (it != counts.end()){
      it->second++;
   } else {
      counts[numbers[i]] = 1;
   }
}

... затем перебирать карту, чтобы распечатать результаты.

РЕДАКТИРОВАТЬ: Как предлагает lazypython: если у вас есть расширения TR1 [wikipedia.org], unordered_map должен иметь лучшую производительность ...

typedef std::tr1::unordered_map<int,unsigned int> CounterMap;
CounterMap counts;
for (int i = 0; i < numbers.size(); ++i)
{
   CounterMap::iterator it(counts.find(numbers[i]));
   if (it != counts.end()){
      it->second++;
   } else {
      counts[numbers[i]] = 1;
   }
}
8
ответ дан 6 December 2019 в 09:21
поделиться

Использование карты - это практическое решение. Что вам нужно сделать, так это решить эту проблему :)

Это называется частотомером. Итак, у вас есть отсортированный вектор, и все, что вам нужно сделать, это подсчитать последовательные равные числа. Другими словами, вы должны сравнить каждое число с его преемником.

for(size_t i = 0; i < numbers.size(); i++)
{
    size_t count = 1;

    size_t limit = numbers.size() - 1;
    while(i < limit  && numbers[i] == numbers[i+1])
    {
        count++;
        i++;
    }

    std::cout << numbers[i] << "\t" << count << std::endl;
}   
4
ответ дан 6 December 2019 в 09:21
поделиться

Эта программа читает строки чисел из файла txt, преобразует их в целые числа, сохраняет их в векторе , и затем пытается вывести их в организованный мод вот так .... (выделено автором)

В чем смысл этого шага хранения? Если вы читаете числа из файла, значит, они у вас уже есть в порядке, готовые к обработке (подсчету) по одному, когда вы их встретите.

Однако мне нужен способ, чтобы он знал, когда он видит новый номер.

Советую вам взглянуть на std :: set или std :: map . Я полагаю, что любой из этих контейнеров сделает то, что вы ищете.

1
ответ дан 6 December 2019 в 09:21
поделиться

Std :: count () прекрасно отвечает всем требованиям.

std::vector<int>::const_iterator cur = numbers.begin();
std::vector<int>::const_iterator last = numbers.end();
while (cur != last) {
    unsigned cnt = std::count(cur, last, *cur);
    std::cout << *cur;
    if (cnt != 1) {
        std::cout << " " << c;
    }
    std::cout << std::endl;
    int saved = *cur;
    while (*cur == saved) {
        ++cur;
    }
}

Конечно, существует множество других алгоритмов, которые будут выполнять ту же работу. Поиграйте с такими вещами, как std :: equal_range () в сочетании с std :: distance () , так же хорошо справится с этой задачей.

1
ответ дан 6 December 2019 в 09:21
поделиться

Это было весело:

#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

struct IncrementMap
{
    IncrementMap(std::map<int,int>& m): m_map(m)    {}
        void operator()(int val) const
    {
        ++m_map[val];
    }
    std::map<int,int>& m_map;
};
struct SpecialPrint
{
    SpecialPrint(std::ostream& s):  m_str(s)    {}
    void operator()(std::map<int,int>::value_type const& value) const
    {
        m_str << value.first;
        if (value.second != 1)
        {
            m_str << "\t" << value.second;
        }
        m_str << "\n";
    }
    std::ostream&   m_str;
};
int main()
{
    std::fstream        x("Plop");
    std::map<int,int>   data;

    std::for_each(  std::istream_iterator<int>(x),
                     std::istream_iterator<int>(),
                     IncrementMap(data)
                );
    std::for_each(  data.begin(),
                    data.end(),
                    SpecialPrint(std::cout)
                );
}
0
ответ дан 6 December 2019 в 09:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: