Normalna postać Chomsky'ego pozwala algorytmowi wielomianowemu decydować, czy gramatyka może wygenerować ciąg. Algorytm jest dość zręczny, jeśli znasz programowanie dynamiczne ...
Jeśli długość twojego wejścia ( ) wynosi to bierzesz tablicę 2d ( ) o wartości dim x .n A n nInAnn
G I ( i , j )A[i,j] oznacza wszystkie symbole w gramatyce które mogą wyprowadzić podłańcuch .GI(i,j)
Tak więc na koniec, jeśli zawiera symbol początkowy ( ), oznacza to, że ciąg I można uzyskać przez co chcieliśmy sprawdzić.S S.A[1,n]SS
def decide (string s,grammar G):
//base case
for i=1 to n:
N[i,i]=I[i] //as the substring of length one can be generated by only a
terminal.
//end base case
//induction
for s=1 to n: //length of substring
for i=1 to n-s-1: //start index of substring
for j=i to i+s-1: //something else
if there exists a rule A->BC such that B belongs to N[i,j] and C
belongs to N[j+1,i+s-1] then add A to N[i,i+s-1]
//endInduction
if S belongs to N[1,n] then accept else reject.
Wiem, że indeksy wydają się dość szalone. Ale w zasadzie oto, co się dzieje.
Myślę, że podstawowy przypadek jest całkiem jasny.
W kroku indukcyjnym budujemy rozwiązanie dla podciągu o długości ze wszystkich rozwiązań o długości mniejszej niż .sss
Powiedzmy, że znajdujesz rozwiązanie dla podłańcucha o długości zaczynając od indeksu . Następnie należy uruchomić pętlę (coś innego ..... część), która sprawdza, czy nie jest to regułą ( ) takie, że i wywodzą się dwie sąsiadujące i rozłączne podciągi sub a jeśli tak dodać wszystkie takie „s do .1 A - > B C B C A N [ 1 , 6 ]5sub
1A−>BCBCAN[1,6]
Wreszcie, jeśli masz symbol początkowy w to akceptujesz!N[1,n]