Есть ли способ реализовать это с помощью преобразования вместо for_each?Если да, то лучше ли это делать? - PullRequest
3 голосов
/ 05 апреля 2019

Учитывая строку s, как я могу использовать transform для создания unordered_map, который содержит количество встречений каждого символа? Стоит ли беспокоиться?

Первоначально я думал о том, чтобы использовать преобразование, но я не был уверен, как реализовать часть «значение приращения, если существует, иначе добавить». Вместо этого я использовал for_each.

Использование for_each:

unordered_map<char, int> charMap;
for_each(begin(s), end(s), [&charMap](char c){charMap[c]++;});

Я надеялся, что смогу сделать что-то подобное, но для карты вместо мультикарты:

unordered_multimap<char, int> charMap2;
transform(begin(s), end(s), inserter(charMap2, begin(charMap2)), [&](char c){
        return make_pair(c, 1);
        });

UPDATE: Посмотрите комментарий @ patatahooligan, чтобы узнать, почему трансформация (предназначенная для преобразований 1-к-1), хотя и достаточно хакерская, чтобы заставить ее работать, может не подходить здесь. Смотрите ответ Максима (принятый) для более подходящих стратегий.

1 Ответ

4 голосов
/ 05 апреля 2019

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

unordered_map<char, int> charMap;
for(char c : s) 
    ++charMap[c];

Вы можете сделать его еще быстрее, если заменитеunordered_map<char, int> с int[256]:

int charMap[UCHAR_MAX + 1] = {}; // Zero-initialized.
for(unsigned char c : s) 
    ++charMap[c];

И если вам нужно unordered_map<char, int>, вы можете построить его из этого int[256] массива:

unordered_map<char, int> charMap2;
for(auto const& count : charMap)
    if(count)
        charMap2[&count - charMap] = count;

Я думаю, используя int charMap[256] окупается только тогда, когда строка s несколько длинна.

...