Sonlu otomatlardan normal ifadelere dönüşüm yapmak için birkaç yöntem vardır. Burada genelde okulda öğretilen, çok görsel olanı anlatacağım. Uygulamada en çok kullanılan olduğuna inanıyorum. Ancak, algoritmayı yazmak o kadar da iyi bir fikir değil.
Devlet kaldırma yöntemi
Bu algoritma, otomatın grafiğini kullanmakla ilgilidir ve bu nedenle ... durum kaldırma gibi grafik ilkellerine ihtiyaç duyduğundan algoritmalar için çok uygun değildir. Bunu daha yüksek seviyeli ilkel kullanarak tarif edeceğim.
Anahtar fikir
Buradaki fikir, kenarlardaki etiketleri tutarlı tutarken, kenarlarda düzenli ifadeleri düşünmek ve ardından ara durumları kaldırmaktır.
Ana desen, aşağıdaki şekillerde görülebilir. İlki arasında normal ifadeler olan e , f , g , h , i etiketlerine sahip ve q ' yu kaldırmak istiyoruz .p,q,re,f,g,h,iq
Kaldırıldıktan sonra, birlikte oluştururuz ( p ve r arasındaki diğer kenarları korurken ancak bu gösterilmez):e,f,g,h,ipr
Örnek
Raphael'in cevabındakiyle aynı örneği kullanarak :
art arda kaldırıyoruz :q2
ve :q3
Sonra biz hala gelen ifadeye Yıldız eklemek zorunda ile q 1 . Bu durumda, son durum da başlangıçta olduğundan gerçekten bir yıldız eklememiz gerekiyor:q1q1
(ab+(b+aa)(ba)∗(a+bb))∗
Algoritma
L[i,j]
, dilin düzenli ifadesi olan için q, j . İlk önce tüm çoklu kenarları kaldırıyoruz:qiqj
for i = 1 to n:
for j = 1 to n:
if i == j then:
L[i,j] := ε
else:
L[i,j] := ∅
for a in Σ:
if trans(i, a, j):
L[i,j] := L[i,j] + a
Şimdi, devlet kaldırma. Biz devlet kaldırmak istediğinizi varsayalım :qk
remove(k):
for i = 1 to n:
for j = 1 to n:
L[i,i] += L[i,k] . star(L[k,k]) . L[k,i]
L[j,j] += L[j,k] . star(L[k,k]) . L[k,j]
L[i,j] += L[i,k] . star(L[k,k]) . L[k,j]
L[j,i] += L[j,k] . star(L[k,k]) . L[k,i]
star(ε)=ε
e.ε=e
∅+e=e
∅.e=∅
∅εqiqkqjqk
Şimdi nasıl kullanılır remove(k)
? Son halleri veya ilk halleri hafifçe silmemelisiniz, aksi halde dilin bölümlerini özleyeceksiniz.
for i = 1 to n:
if not(final(i)) and not(initial(i)):
remove(i)
Yalnızca bir son durum ve bir başlangıç durum o zaman son ifade şöyledir:qfqs
e := star(L[s,s]) . L[s,f] . star(L[f,s] . star(L[s,s]) . L[s,f] + L[f,f])
Birkaç son durumunuz (veya hatta ilk durumlarınız) varsa, geçişli kapatma yöntemini uygulamaktan başka, bunları birleştirmenin basit bir yolu yoktur. Genellikle bu elle elde edilen bir problem değildir ancak algoritmayı yazarken bu oldukça zordur. Daha basit bir çözüm tüm çiftleri numaralandırmak için ve tüm ifadeler, elde etmek için (daha önce devlet kaldırıldı) grafikte algoritması çalıştırmak varsayılarak , sadece ilk durumu ve nihai sadece Devlet, sonra tüm yapıyorum .(s,f)es,fsfes,f
Bu, ve bunun dilleri ilk yöntemden daha dinamik olarak değiştirmesi, programlama sırasında hataya daha yatkın hale getirir. Başka bir yöntem kullanmanızı öneririm.
Eksileri
Bu algoritmada, örneğin hangi düğümü kaldırmamız gerektiğinin seçilmesi, sondaki son durumların sayısı, son bir durumun da başlangıç olabileceği gerçeği gibi birçok durum vardır.
Şimdi algoritmanın yazıldığına dikkat edin, bu geçişli kapatma yöntemine çok benziyor. Sadece kullanımın içeriği farklı. Algoritmanın uygulanmasını önermiyorum, ancak bunu elle yapmak için yöntemi kullanmak iyi bir fikirdir.