Допустим, вы хотите подсчитать количество символов в тексте.
Самый быстрый способ, который я мог придумать, - это использовать массив вроде unsigned char charcounts[256], инициализировать его нулями, затем смотреть на каждый символ в текстовом вводе и делать charcounts[c]++. затем линейный поиск charcounts[] с использованием двух переменных для отслеживания самого низкого (на данный момент) символа и его счетчика, заменяя его новым символом / счетчиком, когда мы находим более низкий, пока не дойдем до конца.
Таким образом, «текст» будет t = 2, e = 1, x = 1.
Есть ли более быстрый способ сделать это?
подсчитать общее количество вхождений каждого символа в некоторый текст. поэтому «текст» будет t = 2, e = 1, x = 1.
Тед, вы должны отредактировать это важное уточнение в своем вопросе, нажав "изменить" выше
Отлично работает для ANSI, но Unicode - это совсем другое дело.
В общем, вы не можете победить O(n) в асимптотическом смысле, так как вам нужно, по крайней мере, проверить все свои входные данные. Прошлое, вы можете поторговаться за скрытую константу ..





Похоже, это один из самых эффективных способов сделать то, что вы описываете. Я не уверен, что вы хотите сделать со второй частью, похоже, вы хотите найти символ, который имеет минимальное количество вхождений в данных сортировки?
Итак, вы хотите знать символ, который встречается хотя бы в строке, но хотя бы один раз? Как насчет того, чтобы два символа имели одинаковое количество вхождений?
первый (порядковый номер ascii) встречающийся наименее встречающийся символ - мой. Меня в основном просто интересует линейный поиск по массиву counts. это O (n), и мне было любопытно, есть ли более быстрый алгоритм. Я посмотрел на кучи, которые могут возвращать самое низкое в O (1), но настраиваются в O (lg n), что будет O (n lg n)
Вы описали здесь две задачи. Первый - подсчитать, сколько раз каждый символ ASCII встречается в потоке, а второй пытается найти символ с наименьшей частотой.
Первый алгоритм кажется довольно эффективным. Я не могу придумать более быстрого способа.
Однако я менее уверен в вашем втором алгоритме. Вы явно не говорите, почему вы хотите найти символ с наименьшей частотой или каковы входные данные, но я могу представить, что легко можно иметь более одного символа с нулевым счетчиком частоты, так как вы хотите различать их?
Часть первая - Подсчет частот букв Следует отметить две проблемы, предполагая, что здесь используется язык C или C++:
Вторая часть - поиск наименее часто встречающейся буквы
Я пытался принять ваш ответ, но это не сработало. это кажется самым быстрым способом ...
Первая часть вашего алгоритма - это подсчет символов - это просто генерация ключей для сортировки.
Если вы знаете, что используете только алфавитные символы [A-Za-z] *, вы можете оптимизировать свой алгоритм, уменьшив количество используемых сегментов, но это лишь небольшая поправка.
Вторая часть - это просто стабильная сортировка - есть много способов сделать это - страница Википедии о сортировке дает хорошее резюме. Если вас интересует только символ, который встречается меньше всего, то описанный вами метод ("Фаза 2"), вероятно, будет настолько эффективным, насколько это возможно.
Единственный другой способ, которым я могу это улучшить, - это если вы можете разделить свои буквы на фиксированное количество сегментов (скажем, 16) равномерно по диапазону символов, а затем рекурсивно для каждого сегмента. Любые корзины без символов можно выбросить, что сэкономит время на этапе сканирования / сортировки. Точно так же, если в ведре есть один символ, это делается. Вы также должны убедиться, что вы разделяете ведро только на 16, если знаете, что в нем есть более одного разных персонажей.
Использование слова test в качестве примера (при условии, что 4 сегмента и только символы нижнего регистра:
Преимущество этого метода в том, что нам не нужно сканировать каждую букву. Если диапазон символов одинакового размера, тогда оба этих метода в лучшем случае O (n), где n - длина строки (это неизбежно, так как мы всегда должны смотреть на каждый символ), хотя построение списков символов в мой пример может сделать алгоритм таким же плохим, как O (n ^ 2). Однако по мере увеличения диапазона символов, особенно для коротких строк, использование дополнительных сегментов значительно повысит производительность. Для строки Unicode вы можете использовать гибридный подход - например, разделение всех символов, отличных от ascii, на первом этапе и использование вашего более простого метода для части ascii.
Вы пытаетесь узнать, сколько раз каждый символ встречается в строке? Или получить полный список символов (a-zA-Z) и сколько раз каждый из них встречается в строке? Или что-то другое?