Редакция для Подсчёт частот символов
Submitting an official solution before solving the problem yourself is a bannable offence.
1. Идея
Нужно посчитать, сколько раз каждая буква встречается в строке, а затем вывести только те буквы, которые встретились хотя бы один раз.
После подсчёта остаётся правильно отсортировать ответ:
- сначала по убыванию количества;
- если количества равны — по алфавиту.
Так как возможных букв всего 26, удобно хранить их частоты в массиве длины 26.
2. Наблюдения
- Строка состоит только из букв
a–z, значит для каждой буквы можно завести отдельную ячейку массива. - Индекс буквы легко получить как
c - 'a'в C++ илиord(c) - ord('a')в Python. - После одного прохода по строке у нас будут все частоты.
- Выводить нужно не все 26 букв, а только те, у которых частота больше нуля.
- Сортировка выполняется по парам:
- чем больше частота, тем раньше буква должна стоять;
- при равной частоте раньше идёт буква, которая меньше по алфавиту.
3. Алгоритм
- Считать строку
s. - Создать массив
cntиз 26 нулей. - Пройти по всем символам строки и увеличить соответствующий счётчик.
- Сформировать список
letters, куда добавить пары(буква, количество)только для букв с положительной частотой. - Отсортировать
letters:- по убыванию количества;
- при равенстве — по возрастанию буквы.
- Вывести все пары по одной на строке.
4. Почему это работает
После прохода по строке в cnt[i] хранится точное число вхождений буквы с индексом i, то есть буквы a + i. Это верно, потому что каждый символ строки ровно один раз увеличивает счётчик своей буквы.
Далее в список letters попадают все и только те буквы, которые реально встретились в строке, поскольку мы добавляем букву тогда и только тогда, когда её счётчик больше нуля.
После сортировки:
- буквы с большей частотой окажутся раньше, потому что сортировка сравнивает их по количеству в обратном порядке;
- если частоты равны, сортировка сравнивает сами буквы и ставит их в алфавитном порядке.
Значит, итоговый вывод полностью соответствует условию задачи.
5. Сложность
Подсчёт частот занимает O(n), где n — длина строки.
Сортировка выполняется не более чем для 26 букв, поэтому её стоимость равна O(26 log 26), то есть это константа.
Итоговая сложность: O(n).
Дополнительная память:
- массив из 26 чисел;
- список не более чем из 26 пар.
Итого по памяти: O(1), если не считать входную строку.
6. Код на C++17
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string s;
cin >> s;
vector<long long> cnt(26, 0);
for (char c : s) {
cnt[c - 'a']++;
}
vector<pair<char, long long>> letters;
for (int i = 0; i < 26; i++) {
if (cnt[i] > 0) {
letters.push_back({char('a' + i), cnt[i]});
}
}
sort(letters.begin(), letters.end(), [](const pair<char, long long>& x, const pair<char, long long>& y) {
if (x.second != y.second) return x.second > y.second;
return x.first < y.first;
});
for (const auto& p : letters) {
cout << p.first << " " << p.second << "\n";
}
return 0;
}
7. Код на Python 3
s = input()
cnt = [0] * 26
for c in s:
cnt[ord(c) - ord('a')] += 1
letters = []
for i in range(26):
if cnt[i] > 0:
letters.append((chr(ord('a') + i), cnt[i]))
letters.sort(key=lambda x: (-x[1], x[0]))
for ch, num in letters:
print(ch, num)
Комментарии