Если я правильно понимаю, что ваши входные строки имеют диапазон "a: a" ... "z: z", и вам просто нужно посчитать появления каждого в потоке, независимо от порядка. Если вашего дистрибутива достаточно, вы можете сосчитать их, используя uint16_t.
Карта реализована с использованием дерева, поэтому массив гораздо более эффективен, чем карта как по памяти, так и по времени.
Таким образом, вы можете определить массив
array<array<uint16_t, 26>, 26> counters = {{}};
и, предполагая, что вы введете, например, input = "c:d"
, вы можете заполнить массив следующим образом
counters[input[0]-'a'][input[2]-'a']++;
Тогда, наконец, вы можете распечатать частоты входа, как это
for (auto i=0; i < counters.size() ; ++i) {
for (auto j=0; j < counters[i].size(); ++j) {
cout<<char(i+'a')<<":"<<char(j+'a')<<" "<<counters[i][j]<<endl;
}
}