Какой идиоматический c способ реализовать самый длинный общий префикс в APL? В тезисе Аарона Хсу, страница нижнего колонтитула 76, говорится:
идиома +.=
вычисляет длину общего префикса, разделяемого двумя путями
Это работает в случае, если нас интересует статья, так как мы гарантируем, что два пути после того, как они перестанут совпадать, больше не будут совпадать. Однако это предположение в общем случае не выполняется . В качестве примеров:
(5⍴1) +.=(1 1 2 2 1) ⍝ expected answer 2. LCP is (1 1)
3
Мы получаем ответ как 3
, поскольку существует совпадение 1
по индексу 5
!
(5⍴1)+.=(6⍴2) ⍝ expected answer: 0. NOT length error
LENGTH ERROR
Другая проблема заключается в том, что вышеприведенное определение работает только в том случае, если два массива имеют одинаковую форму.
Это меня не устраивает, поэтому:
Q1. Как реализовать самый длинный общий префикс для 1D-массивов в APL, который:
является правильным, даже если массивы имеют повторяющиеся элементы после исходного общего префикса.
Надежно работает для массивов различной формы.
При попытке записать условие, при котором идиома a+.= b
правильно вычисляет LCP, Я пришел к:
если len_common_prefix(a, b) = l
, то для всех i > l, i < len(a), i < len(b), a[i] != b[i]
.
Попытка APL-ify это условие привело меня к:
если len_common_prefix(a, b) = l
, то +/l↓a=b
равно 0
.
Q2. Вышеприведенное определение немного некорректно, поскольку для работы =
нам нужно, чтобы длина a
и b
была равна. Как правильно написать это условие в APL, чтобы оно надежно работало для a
и b
различной длины?
Я нашел код в codegolf.stackexchange для самого длинного общего префикса , чье предлагаемое решение имеет ту же проблему:
{⊃↓K/⍨=⌿K←↑⍵} (5 ⍴ 1) (1 1 1 0 1) ⍝ expected: (1 1 1)
1 1 1 1
Очевидно, что это та же проблема, что и , при условии, что строки полностью не совпадают после общего префикса , поэтому этот ответ неверно.
Я попытался выполнить поиск по APLCart , который перечисляет:
Cv{⊃⌽⊃(⊢⌈(⌈\(⍵=⊣)+0,¯1↓⊢))/(⌽⍺),⊂0⊣¨⍵}Dv Length of longest common substring
Я надеялся изменить его, чтобы создать самый длинный общий префикс. При попытке:
'aaaaa' {⊃⌽⊃(⊢⌈(⌈\(⍵=⊣)+0,¯1↓⊢))/(⌽⍺),⊂0⊣¨⍵}'aaaba'
4
К сожалению, это тоже страдает от той же ошибки. Он находит самую длинную общую подпоследовательность , а не самую длинную общую подстроку .
Повторюсь, мои вопросы:
Q1. Как реализовать самый длинный общий префикс для одномерных массивов в APL, который работает правильно для строк разной длины?
Q2. Как записать условие:
если len_common_prefix(a, b) = l
, то для всех i > l, i < len(a), i < len(b), a[i] != b[i]
.
в стиле APL?