Algoritma Kurungan Seimbang di Jawa

1. Gambaran keseluruhan

Balancing Bracket, juga dikenali sebagai Balanced Parentheses, adalah masalah pengaturcaraan yang biasa.

Dalam tutorial ini, kita akan mengesahkan sama ada tanda kurung dalam rentetan tertentu seimbang atau tidak.

Jenis tali ini adalah sebahagian daripada apa yang dikenali sebagai bahasa Dyck.

2. Penyataan Masalah

Braket dianggap sebagai salah satu karakter berikut - “(“, “)”, “[“, “]”, “{“, “}”.

Satu set tanda kurung dianggap sebagai pasangan yang cocok jika braket pembuka , "(", "[", dan "{", terjadi di sebelah kiri kurungan penutup yang sesuai , ")", "]", dan "} ", Masing-masing.

Bagaimanapun, tali yang mengandungi pasangan kurungan tidak seimbang jika set kurungan yang dilampirkannya tidak sepadan .

Begitu juga, rentetan yang mengandungi watak bukan tanda kurung seperti az, AZ, 0-9 atau watak khas lain seperti #, $, @ juga dianggap tidak seimbang .

Sebagai contoh, jika inputnya adalah "{[(])}", pasangan kurung siku, "[]", merangkumi satu kurungan bulat pembukaan tidak seimbang, "(". Begitu juga pasangan kurungan bulat, "() ", Merangkumi satu kurungan siku penutupan tunggal yang tidak seimbang,"] ". Oleh itu, rentetan input" {[(])} "tidak seimbang

Oleh itu, rentetan yang mengandungi watak kurungan dikatakan seimbang sekiranya:

  1. Braket pembuka yang sepadan berlaku di sebelah kiri setiap pendakap penutup yang sesuai
  2. Kurung yang dilampirkan dalam kurungan seimbang juga seimbang
  3. Ia tidak mengandungi aksara bukan tanda kurung

Terdapat beberapa kes khas yang perlu diingat: nol dianggap tidak seimbang, sementara tali kosong dianggap seimbang .

Untuk menerangkan lebih lanjut definisi kurungan seimbang kami, mari kita lihat beberapa contoh tanda kurung seimbang:

() [()] {[()]} ([{{[(())]}}])

Dan sebilangan kecil yang tidak seimbang:

abc[](){} {{[]()}}}} {[(])}

Sekarang kita mempunyai pemahaman yang lebih baik mengenai masalah kita, mari kita lihat bagaimana menyelesaikannya!

3. Pendekatan Penyelesaian

Terdapat pelbagai cara untuk menyelesaikan masalah ini. Dalam tutorial ini, kita akan melihat dua pendekatan:

  1. Menggunakan kaedah kelas String
  2. Menggunakan pelaksanaan Deque

4. Persediaan dan Pengesahan Asas

Mari buat dahulu kaedah yang akan kembali benar jika inputnya seimbang dan salah jika input tidak seimbang:

public boolean isBalanced(String str)

Mari pertimbangkan pengesahan asas untuk rentetan input:

  1. Sekiranya input nol dilalui, maka tidak seimbang.
  2. Agar tali seimbang, pasangan kurungan pembuka dan penutup harus sepadan. Oleh itu, adalah selamat untuk mengatakan bahawa tali input yang panjangnya ganjil tidak akan seimbang kerana akan mengandungi sekurang-kurangnya satu pendakap yang tidak sepadan.
  3. Seperti pernyataan masalah, tingkah laku seimbang harus diperiksa di antara tanda kurung. Oleh itu, sebarang rentetan input yang mengandungi watak bukan tanda kurung adalah rentetan tidak seimbang.

Memandangkan peraturan ini, kami dapat menerapkan pengesahan:

if (null == str || ((str.length() % 2) != 0)) { return false; } else { char[] ch = str.toCharArray(); for (char c : ch) { if (!(c == '' || c == ']' || c == ')')) { return false; } } }

Setelah rentetan input disahkan, kita dapat terus menyelesaikan masalah ini.

5. Menggunakan Kaedah String.replaceAll

Dalam pendekatan ini, kita akan mencari rentetan input yang menghapus kejadian “()”, “[]”, dan “{}” dari string menggunakan String.replaceAll. Kami meneruskan proses ini sehingga tidak ada lagi kejadian yang dijumpai dalam rentetan input.

Setelah proses selesai, jika panjang tali kami adalah sifar, maka semua pasangan kurungan yang sepadan telah dikeluarkan dan rentetan input seimbang. Namun, jika panjangnya tidak sifar, maka beberapa kurungan pembuka atau penutup yang tidak dapat ditandingi masih terdapat dalam tali. Oleh itu, rentetan input tidak seimbang.

Mari lihat pelaksanaannya dengan lengkap:

while (str.contains("()") || str.contains("[]") || str.contains("{}")) { str = str.replaceAll("\\(\\)", "") .replaceAll("\\[\\]", "") .replaceAll("\\{\\}", ""); } return (str.length() == 0);

6. Menggunakan Deque

Deque adalah bentuk Antrian yang menyediakan operasi tambah, ambil dan intip di kedua-dua hujung barisan. Kami akan memanfaatkan ciri pesanan Last-In-First-Out (LIFO) struktur data ini untuk memeriksa keseimbangan dalam rentetan input.

Pertama, mari kita membina Deque kami :

Deque deque = new LinkedList();

Perhatikan bahawa kami telah menggunakan LinkedList di sini kerana menyediakan implementasi untuk antara muka Deque .

Sekarang deque kita dibina, kita akan melengkapkan setiap watak rentetan input satu persatu. Sekiranya watak itu adalah tanda kurung pembuka, maka kita akan menambahkannya sebagai elemen pertama dalam Deque :

if (ch == '{' || ch == '[' || ch == '(') { deque.addFirst(ch); }

Tetapi, jika watak itu adalah tanda kurung penutup, maka kami akan melakukan beberapa pemeriksaan pada LinkedList .

Pertama, kami memeriksa sama ada LinkedList kosong atau tidak. Senarai kosong bermaksud bahawa kurungan penutup tidak dapat ditandingi. Oleh itu, rentetan input tidak seimbang. Oleh itu, kami kembali palsu .

Walau bagaimanapun, jika LinkedList tidak kosong, maka kita melihat watak terakhirnya menggunakan kaedah peekFirst . Sekiranya ia dapat dipasangkan dengan braket penutup, maka kami membuang watak paling utama ini dari senarai menggunakan kaedah removeFirst dan beralih ke lelaran seterusnya pada gelung:

if (!deque.isEmpty() && ((deque.peekFirst() == '{' && ch == '}') || (deque.peekFirst() == '[' && ch == ']') || (deque.peekFirst() == '(' && ch == ')'))) { deque.removeFirst(); } else { return false; }

Pada akhir gelung, semua watak diperiksa keseimbangan, jadi kita dapat kembali benar . Berikut adalah pelaksanaan lengkap pendekatan berasaskan Deque :

Deque deque = new LinkedList(); for (char ch: str.toCharArray()) { if (ch == '{' || ch == '[' || ch == '(') { deque.addFirst(ch); } else { if (!deque.isEmpty() && ((deque.peekFirst() == '{' && ch == '}') || (deque.peekFirst() == '[' && ch == ']') || (deque.peekFirst() == '(' && ch == ')'))) { deque.removeFirst(); } else { return false; } } } return true;

7. Kesimpulannya

Dalam tutorial ini, kami membincangkan penyataan masalah Kurungan Berkurang dan menyelesaikannya dengan menggunakan dua pendekatan yang berbeza.

Seperti biasa, kodnya terdapat di Github.