Membuat alternatif yang lebih cepat untuk {PatternSequence [1, PatternSequence [2, 3 ..] ..] ..}
Saya perlu memperbaiki pola atau mengganti pendekatan.
Ini paling baik dijelaskan dengan sebuah contoh
Untuk hierarki / urutan yang diberikan oleh daftar misalnya:
order = {1, 2, 3}
dan daftar:
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
}
Saya perlu memverifikasi bahwa listcocok dengan urutan yang ditentukan oleh order:
MatchQ[list, {PatternSequence[1, PatternSequence[2, 3 ..] ..] ..}]
Pola ini berskala sangat buruk, karena pola itu tidak akan menyelesaikan evaluasi.
Fungsi ini hanya mengambil listargumen, pertimbangkan konstanta urutan. Pola tidak perlu dibuat secara otomatis.
Jawaban
Hal berikut tampaknya berhasil untuk saya, kecuali saya melewatkan sesuatu:
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
]
]
(Bagian Replace[match[{rest}][#], False :> Return[False, Map]]&ini opsional dan pada prinsipnya dapat diganti dengan hanya match[{rest}]).
Contoh:
match[{1, 2, 3}][list] // AbsoluteTiming
match[{1, 2, 3}][Append[list, 1]] // AbsoluteTiming
(* {0.00038, True} *)
(* {0.000383, False} *)
Solusi ini mencoba untuk mengurangi daftar menjadi daftar satu jenis elemen, jika berhasil maka daftar mengikuti pola yang ditentukan.
MatchQ[
SequenceReplace[
SequenceReplace[list, {2, 3 ..} :> x],
{1, x ..} :> y
],
{y ..}
] // AbsoluteTiming
{0.0019598, True}
Ini adalah contoh mesin negara yang direkomendasikan Daniel dalam komentar:
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}