Предположим, у меня есть два списка, один - это текст t
, второй - список символов c
. Я хочу подсчитать, сколько раз каждый символ появляется в тексте.
Это легко сделать с помощью следующего кода APL.
+⌿t∘.=c
Однако это медленно. Он берет внешнее произведение, затем суммирует каждый столбец.
Это алгоритм O (нм), где n и m - это размер t
и c
.
Of Конечно, я могу написать процедурную программу на APL, которая считывает t
символ за символом и решает эту проблему за O (n + m) (предполагая идеальное хеширование).
Есть ли способы сделать это быстрее в APL без циклов (или условных)? Я также принимаю решения в J.
Edit: Фактически я делаю это там, где текст намного короче, чем список символов (символы не ascii). Я рассматриваю, где текст имеет длину 20, а список символов - тысячи.
Существует простая оптимизация , если n меньше m .
w ← (∪t)∩c
f ← +⌿t∘.=w
r ← (⍴c)⍴0
r[c⍳w] ← f
r
w содержит только символы в t , поэтому размер таблицы зависит только от t, а не от c. Этот алгоритм работает за O (n ^ 2 + m log m). Где m log m - время выполнения операции пересечения.
Однако субквадратичный алгоритм по-прежнему предпочтителен на тот случай, если кто-то предоставил огромный текстовый файл.