Membilang Perkataan dalam Rentetan dengan Java

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan membahas berbagai cara menghitung kata dalam rentetan tertentu menggunakan Java.

2. Menggunakan StringTokenizer

Cara mudah untuk menghitung kata dalam rentetan di Java adalah dengan menggunakan kelas StringTokenizer :

assertEquals(3, new StringTokenizer("three blind mice").countTokens()); assertEquals(4, new StringTokenizer("see\thow\tthey\trun").countTokens());

Perhatikan bahawa StringTokenizer secara automatik menjaga ruang kosong untuk kita , seperti tab dan pengembalian kereta.

Tetapi, ini mungkin berlaku di beberapa tempat, seperti tanda hubung:

assertEquals(7, new StringTokenizer("the farmer's wife--she was from Albuquerque").countTokens());

Dalam kes ini, kami ingin "isteri" dan "dia" menjadi kata yang berbeza, tetapi kerana tidak ada ruang kosong di antara mereka, lalai gagal kami.

Nasib baik, StringTokenizer menghantar dengan konstruktor lain. Kita boleh memasukkan pembatas ke dalam konstruktor untuk membuat kerja di atas:

assertEquals(7, new StringTokenizer("the farmer's wife--she was from Albuquerque", " -").countTokens());

Ini sangat berguna ketika cuba mengira perkataan dalam rentetan dari sesuatu seperti fail CSV:

assertEquals(10, new StringTokenizer("did,you,ever,see,such,a,sight,in,your,life", ",").countTokens());

Oleh itu, StringTokenizer mudah, dan membuat kita hampir sampai di sana.

Mari kita lihat bagaimana ungkapan biasa tenaga kuda tambahan yang dapat memberi kita.

3. Ungkapan Biasa

Agar kita dapat menghasilkan ungkapan biasa yang bermakna untuk tugas ini, kita perlu menentukan apa yang kita anggap sebagai kata: kata bermula dengan huruf dan berakhir sama ada dengan spasi atau tanda baca .

Dengan pemikiran ini, diberi rentetan, apa yang ingin kita lakukan adalah memisahkan rentetan itu pada setiap titik yang kita hadapi dengan spasi dan tanda baca, lalu hitung kata-kata yang dihasilkan.

assertEquals(7, countWordsUsingRegex("the farmer's wife--she was from Albuquerque"));

Mari kita lakukan sedikit untuk melihat kekuatan regex

assertEquals(9, countWordsUsingRegex("no&one#should%ever-write-like,this;but:well"));

Tidak praktikal untuk menyelesaikannya hanya dengan menyerahkan pembatas ke StringTokenizer kerana kita harus menentukan pembatas yang sangat panjang untuk mencuba dan menyenaraikan semua tanda baca yang mungkin.

Ternyata kita benar-benar tidak perlu berbuat banyak, meneruskan regex [\ pP \ s && [^ ']] + ke kaedah split kelas String akan melakukan silap mata :

public static int countWordsUsingRegex(String arg) { if (arg == null) { return 0; } final String[] words = arg.split("[\pP\s&&[^']]+"); return words.length; }

The regex [\ pP \ s && [^ ']] + menemui panjang sama ada tanda baca atau spasi dan mengabaikan tanda baca tanda titik.

Untuk mengetahui lebih lanjut mengenai ungkapan biasa, lihat Ekspresi Biasa di Baeldung.

4. Gelung dan String API

Kaedah lain adalah mempunyai bendera yang mengawasi kata-kata yang pernah ditemui.

Kami menetapkan bendera ke WORD ketika menemui kata baru dan meningkatkan jumlah kata, kemudian kembali ke SEPARATOR ketika kita menemui kata bukan (tanda baca atau spasi).

Pendekatan ini memberikan hasil yang sama dengan pernyataan biasa:

assertEquals(9, countWordsManually("no&one#should%ever-write-like,this but well")); 

Kita harus berhati-hati dengan kes khas di mana tanda baca bukan pemisah kata , misalnya:

assertEquals(6, countWordsManually("the farmer's wife--she was from Albuquerque"));

Apa yang kita mahukan di sini adalah menghitung "petani" sebagai satu kata, walaupun kerasulan "" "adalah tanda baca.

Dalam versi regex, kami memiliki fleksibilitas untuk menentukan apa yang tidak memenuhi syarat sebagai watak menggunakan regex. Tetapi sekarang kita menulis pelaksanaannya sendiri, kita harus menentukan pengecualian ini dengan kaedah yang terpisah :

private static boolean isAllowedInWord(char charAt)  

Oleh itu, apa yang telah kita lakukan di sini adalah dengan membiarkan kata-kata semua watak dan tanda baca sah, kerasulan dalam kes ini.

Kita sekarang boleh menggunakan kaedah ini dalam pelaksanaan kita:

public static int countWordsManually(String arg) { if (arg == null) { return 0; } int flag = SEPARATOR; int count = 0; int stringLength = arg.length(); int characterCounter = 0; while (characterCounter < stringLength) { if (isAllowedInWord(arg.charAt(characterCounter)) && flag == SEPARATOR) { flag = WORD; count++; } else if (!isAllowedInWord(arg.charAt(characterCounter))) { flag = SEPARATOR; } characterCounter++; } return count; }

Keadaan pertama menandakan satu perkataan ketika bertemu dengan satu, dan menambah pembilang. Keadaan kedua memeriksa sama ada watak itu bukan huruf, dan menetapkan bendera ke SEPARATOR .

5. Kesimpulan

Dalam tutorial ini, kami telah mencari cara untuk menghitung kata menggunakan beberapa pendekatan. Kami boleh memilih mana-mana bergantung pada kes penggunaan tertentu kami.

Seperti biasa, kod sumber untuk tutorial ini boleh didapati di GitHub.