Это типичный вариант использования для std::map
.A std::map<char,int>
позволяет легко считать частоту символов (проще обрабатывать вводимые пользователем символы, а не преобразовывать их в числа).
Это в основном все, что вам нужно:
#include <iostream>
#include <iterator>
#include <map>
int main(){
std::istream_iterator<char> it( std::cin );
std::istream_iterator<char> end_of_input;
std::map<char,int> data;
while (it != end_of_input ) data[*(it++)]++;
for (const auto& e : data) std::cout << e.first << " " << e.second << "\n";
}
Это, вероятно, много за раз, поэтому давайте пойдем один за другим.
std::istream_iterator<char>
позволяет извлекать символыиз потока, как будто вы перебираете контейнер.Таким образом, while
повторяется std::cin
, пока не достигнет конца ввода.Затем *(it++)
увеличивает итератор и возвращает символ, извлеченный из потока.data[x]++
обращается к значению на карте для ключа x
и увеличивает его значение.Если на карте еще нет значения ключа, для него по умолчанию устанавливается значение 0
.
Для ввода: 11223 он печатает
1 2
2 2
3 1
У вашего кода есть некоторые проблемы, не уверен, смогу ли я их всех перехватить ...
Вы используете VLA (переменнаядлина массивов) здесь: int a[n];
.Это расширение компилятора, а не стандартное c ++.
Вы получаете доступ к массиву за пределами.Когда i == 0
, тогда j
поднимается до j<n-i-1 == n-1
, а затем вы получаете доступ к a[j+1] == a[n]
, но последний действительный индекс в массиве - n-1
.Та же проблема в другом цикле (a[m+1]
).
Предполагая, что ваша сортировка работает, последний цикл почти дает вам количество элементов, но не совсем, чтобы исправить это, вы можете изменить его на ...
int current = a[0];
int counter = 1;
for(int m=1;m<n;m++) {
if(a[m] == current) {
counter++;
} else {
std::cout << current << " appears " << counter << " times" << endl;
counter=1; // note: minimum freq is 1 not 0
current = a[m];
}
}