{PatternSequence [1, PatternSequence [2, 3 ..] ..] ..}에 대한 더 빠른 대안 만들기
Sep 23 2020
패턴을 개선하거나 접근 방식을 전환해야합니다.
예를 통해 가장 잘 설명됩니다.
목록에 의해 주어진 계층 / 순서의 경우 예 :
order = {1, 2, 3}
및 목록 :
list = {
1, 2, 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3,
3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3
}
list다음에 의해 정의 된 시퀀스와 일치 하는지 확인해야합니다 order.
MatchQ[list, {PatternSequence[1, PatternSequence[2, 3 ..] ..] ..}]
이 패턴은 확장이 매우 나빠서 이미 평가가 끝나지 않을 것입니다.
함수는 list인수 로만 취해야 하며 순서 상수를 고려하십시오. 패턴은 자동으로 구성 할 필요가 없습니다.
답변
10 LeonidShifrin Sep 23 2020 at 22:53
내가 뭔가를 놓치지 않는 한 다음은 나를 위해 작동하는 것 같습니다.
ClearAll[match]
match[{}][{}] := True;
match[{fst_, rest___}][l_List] :=
And @@ Map[
Replace[
match[{rest}][#],
False :> Return[False, Map]
]&,
Replace[
ReplaceList[
l,
{
{___, fst, middle : Except[fst] ..., fst, ___} :> {middle},
{___, fst, r : Except[fst] ...} :> {r}
}
],
{} -> False
]
]
(이 부품 Replace[match[{rest}][#], False :> Return[False, Map]]&은 선택 사항이며 원칙적으로로만 교체 할 수 있습니다 match[{rest}].)
예:
match[{1, 2, 3}][list] // AbsoluteTiming
match[{1, 2, 3}][Append[list, 1]] // AbsoluteTiming
(* {0.00038, True} *)
(* {0.000383, False} *)
10 C.E. Sep 24 2020 at 02:44
이 솔루션은 목록을 단일 유형의 요소 목록으로 줄이려고합니다. 성공하면 목록은 규정 된 패턴을 따릅니다.
MatchQ[
SequenceReplace[
SequenceReplace[list, {2, 3 ..} :> x],
{1, x ..} :> y
],
{y ..}
] // AbsoluteTiming
{0.0019598, True}
이것은 Daniel이 코멘트에서 추천 한 상태 머신에 대한 것입니다.
f[1, 2] = 2;
f[2, 3] = 3;
f[3, 2] = 2;
f[3, 1] = 1;
f[3, 3] = 3;
f[_, _] := Throw[False]
And[
First[list] == 1 && Last[list] == 3,
Catch[Fold[f, list]; True]
] // AbsoluteTiming
{0.0000455, True}