2017-09-09 11 views
2

Wie würde ich fortlaufende Wiederholung einer Zeichenfolge in einer Liste in Prolog suchen.Finden Sie Wiederholungen in einer Liste

Was ich genau das zu finden, zum Beispiel versuchen, ist dies:

input => output 
AAAAAA => 6*(A) 
ABABAB => 3*(AB) 
ABCABCABC => 3*(ABC) 

ich eine DCG Grammatik für diese geschrieben und ich versuche, es mir dies als ein Ergebnis zu haben geben.

Hier ist die Grammatik, falls erforderlich:

exp --> term. 
exp --> term, [+], exp. 

term --> factor. 
term --> digit, [*], exp. 

factor --> elem. 
factor --> ['S'], ['['], sym, [']']. %S[(A)(B),(C)] 
factor --> ['<'], alt, ['>'], ['/'], ['<'], alt, ['>']. %<(A)>/<(B)(C)(D)> 
factor --> ['('], exp, [')']. 

sym --> factor. 
sym --> factor, [','], factor. 
sym --> factor, sym. 

alt --> factor. 
alt --> factor, alt. 

elem --> char. 
elem --> char, elem. 
char --> [D], {is_alnum(D)}. 
digit --> [D], {is_alnum(D)}. 
digit --> [D], {number(D)}. 

nbr_to_char(N, Cs) :- 
    name(Cs, [N]). 
str_to_list(S, Cs) :- 
    name(S, Xs), 
    maplist(nbr_to_char, Xs, Cs). 

eval(L) :- 
    str_to_list(L, X), 
exp(X, []). 

Vielen Dank für jede Hilfe.

+0

Vielleicht wäre es nett, die Grammatik zu bieten? –

+0

Ich fand es nicht notwendig, da die Grammatik viel mehr Fälle als diese behandelt, aber ich werde es trotzdem sagen. – CpCd0y

+0

Warum würde 'ABCABCAB' zu' 3 * (ABC) 'führen? Und was willst du von AAABBBAAABBB? – lurker

Antwort

2

Ich denke, was Sie suchen, ist Pack (dcg_util). Aber auch prüfen/2 anfügen:

?- A=`ababab`. 
A = [97, 98, 97, 98, 97, 98]. 

?- append([X,X,X],$A). 
X = [97, 98], 
A = [97, 98, 97, 98, 97, 98] ; 
false. 

Nun, wenn wir ein ziemlich mächtiges Konstrukt nur eine einfache Möglichkeit finden, um Listen von wiederholten Variablen zu machen, wir haben, können wir verwenden, um Probleme zu lösen. Lassen Sie uns versuchen:

?- length(L,3),maplist(=(X),L). 
L = [X, X, X]. 

So:

?- length(L,_),maplist(=(X),L),append(L,$A). 
L = [[97, 98, 97, 98, 97, 98]], 
X = A, A = [97, 98, 97, 98, 97, 98] ; 
L = [[97, 98], [97, 98], [97, 98]], 
X = [97, 98], 
A = [97, 98, 97, 98, 97, 98] ; 
^CAction (h for help) ? abort 
% Execution Aborted 

oops, nie endende Geschichte ... aber ein bisschen langweilig. Brauchen Sie ein bisschen mehr Code, Durchsetzung der Domain-Kenntnisse (Absacken, wirklich ...)

?- length($A,U),between(1,U,N),length(L,N),maplist(=(X),L),append(L,$A). 
U = 6, 
N = 1, 
L = [[97, 98, 97, 98, 97, 98]], 
X = A, A = A, A = [97, 98, 97, 98, 97, 98] ; 
U = 6, 
N = 3, 
L = [[97, 98], [97, 98], [97, 98]], 
X = [97, 98], 
A = A, A = [97, 98, 97, 98, 97, 98] ; 
false. 
+0

Ich sehe, danke für deine Antwort :) Das scheint nur für Fälle zu funktionieren, bei denen es nur Wiederholungen gibt bin ich richtig? Sagen wir, ich habe A = 'mabcabc', wie würde ich das gleiche Ergebnis wie A = 'abcabc' finden? Sollte ich alle Sub-Strings testen? – CpCd0y

+1

es ist einfach, Skip-Listen in einem festen Muster einzufügen, betrachten '? - append ([_, X, X, X], $ A) .', aber es ist nicht zu einfach zu verallgemeinern ... Sie sollten wirklich die ausprobieren dcg_util pack, wenn Sie SWI ausführen. Es ist ein bisschen steil zu erfassen, aber ** sehr ** wert. – CapelliC

+0

Oh ok, wenn ich also versuchen wollte, das zu verallgemeinern, würde ich das im Maplist machen? – CpCd0y

Verwandte Themen