Предположим, у меня есть два списка, один - текст t
, один - список символов c
. Я хочу подсчитать, сколько раз каждый символ появляется в тексте.
Это можно сделать легко с помощью следующего кода APL.
+⌿t∘.=c
Однако он медленный. Он берет внешний продукт, затем суммирует каждый столбец.
Это алгоритм O (nm), где n и m - размер t
и c
.
Конечно, я могу написать процедурные программы в 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 - время выполнения операции пересечения.
Однако субквадратичный алгоритм по-прежнему предпочтителен, если кто-то дал огромный текстовый файл.