Гид по технологиям

Как найти наиболее часто встречающийся символ в строке

5 min read Алгоритмы Обновлено 17 Apr 2026
Наиболее частый символ в строке — как найти
Наиболее частый символ в строке — как найти

Печати с буквами, сложенные в стопке

Строки — важная тема на собеседованиях. Практика задач по строкам помогает быстрее решать такие задачи. В этой статье вы узнаете, как найти символ, который встречается в строке чаще других.

Примеры для понимания задачи

Пример 1: Пусть задана строка «Makeuseof». Символ «e» встречается 2 раза, все остальные — по одному. Значит, «e» — наиболее частый.

Пример 2: Пусть задана строка «She sees cheese». Символ «e» встречается 6 раз, все остальные — реже. Значит, «e» — наиболее частый.

Подход для поиска наиболее частого символа в строке

Самый эффективный и распространённый способ — использовать хэширование: пройти строку и подсчитать частоту каждого символа в фиксированном массиве (например, по кодам ASCII) или в словаре/хэше. После этого найти индекс (символ) с максимальной частотой.

Идея для строки “Makeuseof”:

frequency[‘M’] = 1

frequency[‘a’] = 1

frequency[‘k’] = 1

frequency[‘e’] = 2

frequency[‘u’] = 1

frequency[‘s’] = 1

frequency[‘o’] = 1

frequency[‘f’] = 1

Максимальное значение — 2, индекс соответствует символу ‘e’.

C++ программа для поиска символа с наибольшей частотой

Ниже — исходный код на C++, реализующий описанный метод.

// C++ program to find the character  
// having the highest frequency in a string  
#include   
#include   
#define ASCII_SIZE 256  
using namespace std;  
  
char maxFrequencyChar(string str)  
{  
 // Array to store frequency of each characters  
 // Initialized the frequency of each character as 0  
 int frequency[ASCII_SIZE] = {0};  
  
 // Finding length of the input string  
 int lenOfStr = str.length();  
  
 // Initialize maxFrequency variable  
 int maxFrequency = -1;  
  
 // Initialize maxFrequencyChar variable  
 char maxFrequencyChar;  
  
 // Traversing and maintaining the  
 // frequency of each characters  
 for (int i = 0; i < lenOfStr; i++)  
 {  
 frequency[str[i]]++;  
 if (maxFrequency < frequency[str[i]])  
 {  
 maxFrequency = frequency[str[i]];  
 maxFrequencyChar = str[i];  
 }  
 }  
  
 return maxFrequencyChar;  
}  
  
// Driver Code  
int main()  
{  
 string str1 = "Which witch is which?";  
 cout << "str1: " << str1 << endl;  
 cout << "The highest frequency character is: " << maxFrequencyChar(str1) << endl;  
  
 string str2 = "He threw three free throws";  
 cout << "str2: " << str2 << endl;  
 cout << "The highest frequency character is: " << maxFrequencyChar(str2) << endl;  
  
 string str3 = "Eddie edited it";  
 cout << "str3: " << str3 << endl;  
 cout << "The highest frequency character is: " << maxFrequencyChar(str3) << endl;  
  
 string str4 = "Makeuseof";  
 cout << "str4: " << str4 << endl;  
 cout << "The highest frequency character is: " << maxFrequencyChar(str4) << endl;  
  
 string str5 = "She sees cheese";  
 cout << "str5: " << str5 << endl;  
 cout << "The highest frequency character is: " << maxFrequencyChar(str5) << endl;  
}  
  

Вывод программы (пример):

str1: Which witch is which?  
The highest frequency character is: h  
str2: He threw three free throws  
The highest frequency character is: e  
str3: Eddie edited it  
The highest frequency character is: d  
str4: Makeuseof  
The highest frequency character is: e  
str5: She sees cheese  
The highest frequency character is: e

Python программа для поиска символа с наибольшей частотой

Ниже — реализация на Python. В исходном примере используется массив размера 256 для ASCII.

# Python program to find the character  
# having the highest frequency in a string  
ASCII_SIZE = 256  
  
def maxFrequencyChar(str):  
  
# Array to store frequency of each characters  
    # Initialized the frequency of each character as 0  
    frequency = [0] * ASCII_SIZE  
  
# Initialize maxFrequency variable  
    maxFrequency = -1  
  
    # Initialize maxFrequencyChar variable  
    maxFrequencyChar = ''  
  
# Traversing and maintaining the  
    # frequency of each characters  
for i in str:  
        frequency[ord(i)] += 1  
  
for i in str:  
if maxFrequency < frequency[ord(i)]:  
            maxFrequency = frequency[ord(i)]  
            maxFrequencyChar = i  
  
return maxFrequencyChar  
  
# Driver Code  
str1 = "Which witch is which?"  
print("str1:", str1)  
print("The highest frequency character is:", maxFrequencyChar(str1))  
  
str2 = "He threw three free throws"  
print("str2:", str2)  
print("The highest frequency character is:", maxFrequencyChar(str2))  
  
str3 = "Eddie edited it"  
print("str3:", str3)  
print("The highest frequency character is:", maxFrequencyChar(str3))  
  
str4 = "Makeuseof"  
print("str4:", str4)  
print("The highest frequency character is:", maxFrequencyChar(str4))  
  
str5 = "She sees cheese"  
print("str5:", str5)  
print("The highest frequency character is:", maxFrequencyChar(str5))  

Вывод (пример):

str1: Which witch is which?  
The highest frequency character is: h  
str2: He threw three free throws  
The highest frequency character is: e  
str3: Eddie edited it  
The highest frequency character is: d  
str4: Makeuseof  
The highest frequency character is: e  
str5: She sees cheese  
The highest frequency character is: e

C программа для поиска символа с наибольшей частотой

Пример на C из исходного материала (обратите внимание: в исходнике используются заголовки и стиль, приближённые к C++). Код сохранён для демонстрации подхода в языке C-подобном формате.

// C program to find the character  
// having the highest frequency in a string  
#include   
#include   
#define ASCII_SIZE 256  
using namespace std;  
  
char maxFrequencyChar(char *str)  
{  
 // Array to store frequency of each characters  
 // Initialized the frequency of each character as 0  
 int frequency[ASCII_SIZE] = {0};  
  
 // Finding length of the input string  
 int lenOfStr = strlen(str);  
  
 // Initialize maxFrequency variable  
 int maxFrequency = 0;  
  
 // Initialize maxFrequencyChar variable  
 char maxFrequencyChar;  
  
 // Traversing and maintaining the  
 // frequency of each characters  
 for (int i = 0; i < lenOfStr; i++)  
 {  
 frequency[str[i]]++;  
 if (maxFrequency < frequency[str[i]])  
 {  
 maxFrequency = frequency[str[i]];  
 maxFrequencyChar = str[i];  
 }  
 }  
  
return maxFrequencyChar;  
}  
  
// Driver Code  
int main()  
{  
 char str1[] = "Which witch is which?";  
 printf("str1: %s", str1);  
 printf("The highest frequency character is: %c \n", maxFrequencyChar(str1));  
  
 char str2[] = "He threw three free throws";  
 printf("str2: %s", str2);  
 printf("The highest frequency character is: %c \n", maxFrequencyChar(str2));  
  
 char str3[] = "Eddie edited it";  
 printf("str3: %s", str3);  
 printf("The highest frequency character is: %c \n", maxFrequencyChar(str3));  
  
 char str4[] = "Makeuseof";  
 printf("str4: %s", str4);  
 printf("The highest frequency character is: %c \n", maxFrequencyChar(str4));  
  
 char str5[] = "She sees cheese";  
 printf("str1: %s", str5);  
 printf("The highest frequency character is: %c \n", maxFrequencyChar(str5));  
  
}

Вывод (пример):

str1: Which witch is which?  
The highest frequency character is: h  
str2: He threw three free throws  
The highest frequency character is: e  
str3: Eddie edited it  
The highest frequency character is: d  
str4: Makeuseof  
The highest frequency character is: e  
str5: She sees cheese  
The highest frequency character is: e

JavaScript программа для поиска символа с наибольшей частотой

Реализация на JavaScript сохраняет ту же идею — массив фиксированного размера для кодов символов.

// JavaScript program to find the character  
// having the highest frequency in a string  
let ASCII_SIZE = 256;  
function maxFrequencyChar(str)  
{  
 // Array to store frequency of each characters  
 // Initialized the frequency of each character as 0  
 let frequency = new Array(ASCII_SIZE);  
 for (let i = 0; i < ASCII_SIZE; i++)  
 {  
 frequency[i] = 0;  
 }  
  
// Finding length of the input string  
 let lenOfStr = str.length;  
  
for (let i = 0; i < lenOfStr; i++)  
 {  
 frequency[str[i].charCodeAt(0)] += 1;  
 }  
  
 // Initialize maxFrequency variable  
 let maxFrequency = -1;  
  
// Initialize maxFrequencyChar variable  
 let maxFrequencyChar = '';  
  
 // Traversing and maintaining the  
 // frequency of each characters  
 for (let i = 0; i < lenOfStr; i++)  
 {  
 if (maxFrequency < frequency[str[i].charCodeAt(0)])  
 {  
 maxFrequency = frequency[str[i].charCodeAt(0)];  
 maxFrequencyChar = str[i];  
 }  
 }  
 return maxFrequencyChar;  
}  
  
// Driver Code  
let str1 = "Which witch is which?";  
document.write("str1: " + str1 + "\n");  
document.write("The highest frequency character is: " + maxFrequencyChar(str1) + "\n")  
  
let str2 = "He threw three free throws";  
document.write("str2: " + str2 + "\n");  
document.write("The highest frequency character is: " + maxFrequencyChar(str2) + "\n")  
  
let str3 = "Eddie edited it";  
document.write("str3: " + str3 + "\n");  
document.write("The highest frequency character is: " + maxFrequencyChar(str3) + "\n")  
  
let str4 = "Makeuseof";  
document.write("str4: " + str4 + "\n");  
document.write("The highest frequency character is: " + maxFrequencyChar(str4) + "\n")  
  
let str5 = "She sees cheese";  
document.write("str5: " + str5 + "\n");  
document.write("The highest frequency character is: " + maxFrequencyChar(str5) + "\n")

Вывод (пример):

str1: Which witch is which?  
The highest frequency character is: h  
str2: He threw three free throws  
The highest frequency character is: e  
str3: Eddie edited it  
The highest frequency character is: d  
str4: Makeuseof  
The highest frequency character is: e  
str5: She sees cheese  
The highest frequency character is: e

Анализ временной и пространственной сложности

Для функции maxFrequencyChar() время работы — O(n), где n — длина строки: один проход для подсчёта частот и (в худшем случае) дополнительный проход для поиска максимума, но можно сделать всё в одном проходе. Пространственная сложность — O(1), если используется фиксированный массив (например, размер 256 для ASCII). Если использовать динамический словарь для произвольных символов Unicode, то сложность памяти — O(k), где k — число уникальных символов в строке.

Важно помнить, что «фиксированный массив 256» применим только когда вход ограничен ASCII. Для Unicode (UTF-8/UTF-16) нужен другой подход — словарь/Map или предварительная нормализация.

Когда подход с фиксированным массивом не сработает

  • В строках с Unicode-символами (эмодзи, многобайтовые символы) индексация по байту даст неверный результат. Используйте словарь/Map и работайте с кодовыми точками.
  • Если нужно игнорировать регистр, предварительно приведите строку к одному регистру.
  • Если нужно игнорировать пробелы или знаки пунктуации — отфильтруйте их заранее.
  • В случае равной максимальной частоты (ничья) алгоритм выше возвращает первый встретившийся максимальный символ. Если нужна другая политика (например, минимальный/лексикографический), требуется дополнительная логика.

Альтернативные подходы

  • Сортировка символов и проход по отсортированной строке: O(n log n) по времени, O(1) или O(n) по памяти в зависимости от реализации.
  • Использовать структуру данных Counter (collections.Counter в Python) или HashMap/unordered_map в C++ для гибкой работы с Unicode.
  • Для потоковых входных данных (stream) можно поддерживать счётчики и периодически сохранять топ-k.

Хитрости и эвристики

  • Для ASCII используйте фиксированный массив размера 256 — быстрее и экономнее по памяти.
  • Для текста на естественных языках чаще всего полезно нормализовать строку (Unicode NFC/NFD), убрать диакритические знаки, привести к единому регистру.
  • Если важна скорость и вход очень большой, оцените локальность данных и кэширование: массив по индексам символов работает лучше, чем HashMap.

Небольшая таблица с важными числами

  • Время: O(n)
  • Память: O(1) для фиксированного массива, O(k) для словаря (k — число уникальных символов)
  • Размер массива для ASCII: 256

Проверочные случаи и критерии приёмки

  • Пустая строка -> поведение: можно возвращать пустой символ или бросать исключение.
  • Строка с одним символом -> возвращается этот символ.
  • Строки с Unicode-символами -> результат корректен при использовании Map/словаря.
  • Равная частота -> документировать политику выбора (первый/последний/лексикографический).

Примеры тестов (вход -> ожидаемый символ):

  • “” -> (ошибка или пусто)
  • “aaaa” -> ‘a’
  • “ababa” -> ‘a’ (если выбираем первый встреченный)
  • “A a a” -> зависит от фильтрации/регистра

Decision flowchart

flowchart TD
  A[Есть требование к Unicode?] -->|Да| B{Использовать Map}
  A -->|Нет| C{Вход ограничен ASCII?}
  C -->|Да| D[Использовать массив size=256]
  C -->|Нет| B
  B --> E[Нормализация строки + Map подсчёт]
  D --> E
  E --> F[Найти максимум и применить политику ничьей]

Короткий глоссарий

  • Хэш/словарь: структура, где ключ — символ, значение — счётчик.
  • Кодовая точка: уникальный числовой код символа в Unicode.
  • Нормализация: приведение Unicode-строки к единому представлению.

Заключение

Метод подсчёта частот символов — простой, эффективный и широко применимый. Для ASCII достаточно фиксированного массива размера 256 и линейного времени. Для Unicode и особых требований (регистрозависимость, игнорирование пробелов, политика при ничьей) используйте словари/Map и заранее нормализуйте строку.

Важно: определите требования к входу и правила обработки (регистр, пробелы, пунктуация, Unicode) перед выбором реализации.

Список ключевых выводов:

  • Простое решение: подсчитать частоты и найти максимум — O(n).
  • Для ASCII можно использовать массив размера 256 — O(1) памяти.
  • Для Unicode используйте Map/словарь и нормализацию.
  • Документируйте поведение при ничьей и при пустой строке.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

CSS font-family: как менять шрифты на сайте
Frontend

CSS font-family: как менять шрифты на сайте

График амортизации кредита в Excel — пошагово
Финансы

График амортизации кредита в Excel — пошагово

Разгон Raspberry Pi 4 — безопасный пошаговый гид
Аппаратное обеспечение

Разгон Raspberry Pi 4 — безопасный пошаговый гид

Как запустить Windows 11 на Mac — варианты и советы
Mac

Как запустить Windows 11 на Mac — варианты и советы

Мошенничество с возвратом средств через техподдержку
Безопасность

Мошенничество с возвратом средств через техподдержку

Диагональная обрезка в Canva — как сделать эффектно
Дизайн

Диагональная обрезка в Canva — как сделать эффектно