Mengapa tidak ada permutasi di Regex? (Bahkan jika bahasa reguler tampaknya dapat melakukan ini)


13

Masalah

Tidak ada cara mudah untuk mendapatkan permutasi dengan regex.

  • Permutasi: Mendapatkan kata ("aabc") ke urutan lain, tanpa mengubah jumlah atau jenis huruf.
    w=x1xn
  • Regex: Ekspresi reguler.

Untuk verifikasi:

Jenis solusi yang saya cari

Seharusnya berupa:

  • »Aabc« (atau apa pun yang Anda bisa menggunakan kurung buka dan tutup)
  • (aabc)! (mirip dengan (abc)? tetapi dengan simbol lain pada akhirnya)
  • [aabc]! (mirip dengan [abc] + tetapi dengan simbol lain pada akhirnya)

Keuntungan dari solusi ini

Mereka:

  • mudah
  • mudah beradaptasi
  • dapat digunakan kembali

Kenapa ini harus ada

  • Regex adalah cara untuk menggambarkan tata bahasa dari bahasa reguler. Mereka memiliki kekuatan penuh untuk menjadi jenis bahasa biasa.
  • Katakanlah, bahasa reguler cukup kuat untuk permutasi (bukti di bawah) - mengapa tidak ada cara mudah untuk mengekspresikan ini?

Jadi pertanyaan saya adalah:

  • (Kenapa) Apakah buktiku salah?
  • Jika benar: Mengapa tidak ada cara mudah untuk mengekspresikan permutasi?

Bukti

  • Ekspresi reguler adalah salah satu cara untuk memperhatikan tata bahasa bahasa reguler. Mereka dapat menjelaskan tata bahasa bahasa biasa.
  • Cara lain untuk menggambarkan bahasa biasa (yang memiliki jumlah huruf hingga dalam alfabet) terbatas adalah tata bahasa yang bukan deterministik (dengan jumlah negara terbatas).

Memiliki jumlah huruf yang terbatas saya dapat membuat otomat ini: (Contoh. Formal: lihat di bawah)

Tata bahasa yang menerima permutasi "abbc":

(coba nomor di atas, mungkin seseorang tahu cara membuat bagian ini terlihat lebih baik)

s -> ah¹

s -> bh²

s -> ch³

h¹ -> bh¹¹

h¹ -> ch¹²

h² -> ah¹¹ (tidak ada kesalahan ketik!)

h² -> bh²²

h² -> ch²³

h³ -> ah¹²

h³ -> bh²³

h¹¹ -> bc

h¹¹ -> cb

h¹² -> bb

h²² -> ac

h²² -> ca

h²³ -> ab

h²³ -> ba

Lebih formal: (menggunakan finite-state-automaton tetapi ini bisa dibuat dengan tata bahasa juga)

  • Sebuah kata q (dengan panjang terbatas) yang permutasi apa pun harus mencapai kondisi penerimaan.
  • X adalah alfabet terbatas.
  • Set of state S berisi urutan huruf apa saja hingga panjang q. (Jadi ukuran S adalah terbatas.) Ditambah satu status "any any word".
  • status transisi fungsi d yang mengambil huruf dan bergerak pada status yang sesuai dengan bagian kata yang sekarang dibaca.
  • F adalah himpunan yang menyatakan permutasi yang tepat dari q.

Jadi dimungkinkan untuk membuat otomat kondisi-terbatas untuk menerima permutasi dari kata yang diberikan.

Pindah dengan buktinya

Jadi saya telah membuktikan bahwa bahasa reguler memiliki kekuatan untuk memeriksa permutasi, bukan?

Jadi mengapa tidak ada pendekatan untuk mencapai ini dengan Regex? Ini fungsionalitas yang berguna.


10
Anda dapat membuat daftar semua permutasi kata Anda dengan ekspresi reguler. Ekspresi yang dihasilkan akan cukup besar, tetapi pasti akan menjadi ekspresi reguler.
Yuval Filmus

7
Saya sarankan mengabaikan semua jawaban tentang Teori Komputasi pada stackoverflow. Ini bukan spesialisasi situs itu.
Yuval Filmus

Jawaban pada halaman tertaut Anda di sini - stackoverflow.com/a/3102205/6936386 - tampaknya mudah diadaptasi dan tidak terlalu rumit: ^(a()|a()|b()|c()){4}\2\3\4\5$tampaknya berfungsi (lihat regex101.com/r/9URPpg/4/tests ).
boboquack

7
@ Boboquack Itu bukan ekspresi reguler dalam arti istilah yang digunakan dalam ilmu komputer. (Hal semacam inilah yang tepatnya Yuval sarankan untuk tidak mempercayai jawaban Stack Overflow tentang CS teoretis.)
David Richerby

Jawaban:


37

Teorema dasar teori bahasa formal adalah bahwa ekspresi reguler, tata bahasa reguler, deterministic finite automata (DFAs) dan finite automata (NFA) deterministik semuanya menggambarkan jenis bahasa yang sama: yaitu bahasa reguler. Fakta bahwa kita dapat mendeskripsikan bahasa-bahasa ini dalam banyak cara yang sangat berbeda menunjukkan bahwa ada sesuatu yang alami dan penting tentang bahasa-bahasa ini, dengan cara yang sama seperti kesetaraan mesin Turing, kalkulus lambda dan segala macam hal lainnya menunjukkan bahwa bahasa yang dapat dihitung alami dan penting. Itu bukan hanya artefak dari keputusan acak apa pun yang dibuat oleh penemu asli.

Misalkan kita menambahkan aturan baru untuk menciptakan ekspresi reguler: jika R  adalah ekspresi reguler, maka π(R) adalah ekspresi reguler, dan itu cocok dengan setiap permutasi dari setiap string yang cocok dengan  R . Jadi, misalnya, L(π(abc))={abc,acb,bac,bca,cab,cba}. Masalahnya adalah ini melanggar kesetaraan mendasar yang dijelaskan di atas. L(π((ab)))) adalah bahasa string yang berisi jumlah yang sama a s dan b dan ini bukan bahasa biasa. Bandingkan ini dengan, misalnya, menambahkan operator negasi atau pembalikan ke ekspresi reguler, yang tidak mengubah kelas bahasa yang diterima.

Jadi, untuk menjawab pertanyaan judul, ekspresi reguler tidak dapat melakukan permutasi dan kami tidak menambahkan kemampuan itu karena kemudian ekspresi reguler tidak akan cocok dengan bahasa biasa. Karena itu, ada kemungkinan bahwa "ekspresi reguler dengan permutasi" juga akan menjadi kelas bahasa yang menarik dengan banyak penokohan yang berbeda.


Tetapi L ((ab) *) juga bukan bahasa biasa - jadi L (perm ((ab) *)) tidak dapat menjadi satu. ((ab) * bukan bahasa biasa karena tidak ada jenis memori untuk mengingat berapa banyak pembukaan "a", jadi dengan jumlah negara terbatas Anda tidak dapat memasukkan jumlah yang sama "b".)
Asqiir

9
L((ab)){ε,ab,abab,ababab,abababab,}{ε,ab,aabb,aaabbb,aaaabbbb,}

4
ab

2
Anda sepenuhnya benar. Saya melewatkan titik "menempatkan ekspresi reguler ke satu sama lain", saya hanya berpikir tentang "permutasi kata tetap" tidak "permutasi regex lain" yang tentu saja tidak mungkin.
Asqiir

1
Mungkin ekspresi reguler dengan permutasi menggambarkan kelas bahasa dengan properti yang menarik, tetapi saya tidak pernah mengalami kebutuhan untuk !operator dalam praktik, dan saya kira beberapa orang memiliki, karena mudah diimplementasikan, dan tidak ada implementasi dari ekspresi reguler yang diperluas. telah terlihat mendukungnya.
reinierpost

16

Jadi pertanyaan saya adalah:

  • (Kenapa) Apakah buktiku salah?
  • Jika benar: Mengapa tidak ada cara mudah untuk mengekspresikan permutasi?

"Bukti" Anda hanya melihat permutasi kata tunggal, yang merupakan bahasa terbatas.

Setiap bahasa berhingga adalah reguler (mis. Hanya dengan mendaftar semua anggota dengan |inbetween), tetapi ada bahasa reguler yang tak terbatas (dan itu pada umumnya yang lebih menarik).

Segera setelah Anda mendapatkan ekspresi reguler (atau tata bahasa / otomat) yang menerima bahasa tak terbatas (yaitu ekspresi dengan *operator, atau automaton dengan loop), konstruksi Anda tidak berfungsi lagi (Anda mendapatkan tata bahasa / otomat tak terbatas) ).

Jawaban oleh David Richerby memberikan contoh bahasa biasa yang bahasa permutasinya tidak teratur lagi - semua contoh tersebut adalah bahasa tanpa batas.


8

ΣnΣmO(m)

Jadi dalam beberapa hal, tidak ada cara ringkas untuk menentukan semua permutasi kata.


Ω~(2n)ΣnmO(m)

L(xi,yi)1iN

  • xiyiL
  • ijxiyjLxjyiL

LNLixiyiqixiqiqjijqi=qjxiyjxjyiL

Lnσ1,,σnnSσ1,,σnn/2xSSySSxSySLnSTxSyTLnLn(nn/2)=Ω(2n/n)


Apakah ini berarti 1) dalam teori akan memungkinkan untuk membiarkan »abc« cocok dengan semua {abc, acb, bac, bca, cab, cba} tetapi itu tidak efisien dan akan membuat mereka terlalu lambat karena »abc« akan meluas secara eksponensial ke (abc | acb | bac | bca | cab | cba)? atau 2) Jenis otomat yang saya butuhkan tidak dapat menentukan semua permutasi untuk kata yang diberikan?
Asqiir

1
Berikut adalah ekspresi reguler yang cocok dengan semua permutasi dari abcabc+acd+bac+bca+cab+cba1+3+6+6+1=17abcdefghij.
Yuval Filmus

1
Apa yang saya pahami: Secara teori, bahasa reguler dapat menerima permutasi (demikian juga ekspresi reguler). Tidak ada "cara sederhana" untuk menulis "permutasi abc" seperti »abc«. (Untuk alasan apa pun.)
Asqiir

1
Ya, itu ringkasan yang bagus. Saya akan melihat apakah saya dapat mengajukan argumen sederhana untuk ekspresi reguler.
Yuval Filmus

2
Untuk pembaca masa depan: ini bukan jawaban yang benar! (Koreksi saya jika saya salah.) Cari yang diterima.
Asqiir

0

Mengapa tidak ada cara untuk menulis "permutasi" di Regex

Permutasi bahasa reguler dan tak terbatas (jumlah kata tak terbatas) belum tentu teratur. Dengan demikian, tidak dapat ditulis sebagai regex.

Bukti

Pikirkan bahasanya (ab)*. (Contoh terinspirasi oleh David Richerby .) Salah satu permutasi adalah a*b*. Ini bukan bahasa biasa. qed.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.