Есть ли функция, которая ищет последовательность элементов для подпоследовательности? Ищу аналог StringPosition
для List
s. В моем текущем приложении я работаю со списками целых чисел, но меня заинтересует общая функция FindSequence [list, pattern, n]
, которая найдет первые n
вхождения шаблон
в списке
.
Вот игрушечный пример:
Сгенерируйте данные:
In[1]:= $HistoryLength = 0
Out[1]= 0
In[2]:= Timing[digits = First[RealDigits[\[Pi], 2, 10000000]];]
Out[2]= {26.5, Null}
Давайте преобразуем их в строку, чтобы мы могли сравнить с StringPosition
. Это очень медленно и требует памяти. (Память освобождается, когда оценка заканчивается.)
In[3]:= Timing[str = StringJoin[ToString /@ digits];]
Out[3]= {43.813, Null}
Я ищу эту подпоследовательность:
In[4]:= patt = {1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0,
1, 0, 1, 1};
In[5]:= strpatt = StringJoin[ToString /@ patt];
Поиск строки выполняется очень быстро:
In[6]:= StringPosition[str, strpatt] // Timing
Out[6]= {1.047, {{5737922, 5737943}}}
Это простая реализация поиска числовых массивов.Это медленнее, чем StringPosition
:
In[7]:= Timing[
corr = ListCorrelate[patt, digits];
Select[Flatten@Position[corr, patt.patt],
digits[[# ;; # + Length[patt] - 1]] === patt &]
]
Out[7]= {2.234, {5737922}}
Резюме:
{1,0,1}
, или общие, такие как {1, _, 1}
, хотя последние может вызвать сложности.) Я ожидаю, что у этого будет много решений, некоторые быстрые, некоторые более элегантные, некоторые более общие: -)
Связанные вопросы:
Интересное чтение:
РЕДАКТИРОВАТЬ:
Я только что нашел недокументированный LongestCommonSubsequencePositions
. LongestCommonSubsequencePositions [a, b]
найдет самую длинную общую подпоследовательность списков a
и b
и вернет позицию своего первого вхождения. только в обоих a
и b
. (Задокументированная LongestCommonSubsequence
, о которой я не знал, вернет только саму подпоследовательность, но не ее позицию.)
Это медленнее, чем приведенные выше альтернативы, но работает с общими списками, которые могут содержать любое выражение.
In[57]:= LongestCommonSubsequencePositions[digits, patt] // Timing
Out[57]= {5.25, {{5737922, 5737943}, {1, 22}}}