Лучше, чем
All = Cash | Check | CreditCard
решение, потому что, если Вы добавляете другой метод позже, скажите:
PayPal = 8 ,
Вы будете уже сделаны с тильдой - все, но иметь для изменения все-строки с другим. Так его менее подверженное ошибкам позже.
отношения
Как насчет использования карты, где ключ - это номер, который вы отслеживаете, а значение - количество вхождений?
Если вам нужно использовать вектор, у вас уже есть это отсортировано. Так что просто следите за номером, который вы видели ранее. Если оно совпадает с текущим числом, увеличьте счетчик. Каждый раз, когда число изменяется: распечатайте текущее число и счетчик, сбросьте счетчик, установите число last_seen на новое число.
Вы можете использовать карту чисел для счетчиков:
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;
}
}
Использование карты - это практическое решение. Что вам нужно сделать, так это решить эту проблему :)
Это называется частотомером. Итак, у вас есть отсортированный вектор, и все, что вам нужно сделать, это подсчитать последовательные равные числа. Другими словами, вы должны сравнить каждое число с его преемником.
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;
}
Эта программа читает строки чисел из файла txt, преобразует их в целые числа, сохраняет их в векторе , и затем пытается вывести их в организованный мод вот так .... (выделено автором)
В чем смысл этого шага хранения? Если вы читаете числа из файла, значит, они у вас уже есть в порядке, готовые к обработке (подсчету) по одному, когда вы их встретите.
Однако мне нужен способ, чтобы он знал, когда он видит новый номер.
Советую вам взглянуть на std :: set
или std :: map
. Я полагаю, что любой из этих контейнеров сделает то, что вы ищете.
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 ()
, так же хорошо справится с этой задачей.
Это было весело:
#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)
);
}