Provjerite sadrži li niz više ključnih riječi u Javi

1. Uvod

U ovom brzom vodiču, saznat ćemo kako otkriti više riječi unutar niza.

2. Naš primjer

Pretpostavimo da imamo niz:

String inputString = "zdravo, Baeldung";

Naš je zadatak otkriti je li inputString sadrži "zdravo" i "Baeldung" riječi.

Dakle, stavimo naše ključne riječi u niz:

Niz [] riječi = {"zdravo", "Baeldung"};

Štoviše, redoslijed riječi nije važan, a podudaranja trebaju razlikovati velika i mala slova.

3. Korištenje String.contens ()

Kao početak, pokazat ćemo kako se koristi String.contens () metoda za postizanje našeg cilja.

Krenimo preko niza ključnih riječi i provjerimo pojavu svake stavke unutar inputString:

javna statička logička vrijednost sadrži Riječi (String inputString, String [] stavke) {boolean found = true; for (String item: items) {if (! inputString.contains (item)) {found = false; pauza; }} povratak pronađen; }

The sadrži () metoda će se vratiti pravi ako je inputString sadrži dano artikal. Kada unutar niza nemamo nijednu ključnu riječ, možemo se prestati kretati naprijed i odmah vratiti lažno.

Unatoč činjenici da moramo napisati više koda, ovo je rješenje brzo za jednostavne slučajeve upotrebe.

4. Korištenje String.indexOf ()

Slično rješenju koje koristi String.contens () metoda, indekse ključnih riječi možemo provjeriti pomoću String.indexOf () metoda. Za to nam treba metoda koja prihvaća inputString i popis ključnih riječi:

javna statička logička vrijednost sadržiWordsIndexOf (String inputString, String [] riječi) {boolean found = true; for (String word: words) {if (inputString.indexOf (word) == -1) {found = false; pauza; }} povratak pronađen; }

The indexOf () metoda vraća indeks riječi unutar inputString. Kad u tekstu nemamo riječi, indeks će biti -1.

5. Korištenje regularnih izraza

A sada, upotrijebimo regularni izraz koji odgovara našim riječima. Za to ćemo upotrijebiti Uzorak razred.

Prvo definirajmo nizni izraz. Kako trebamo podudarati dvije ključne riječi, svoje ćemo pravilo regularnog izraza izgraditi s dva lookaheadsa:

Uzorak uzorka = Pattern.compile ("(? =. * Zdravo) (? =. * Baeldung)");

I za opći slučaj:

StringBuilder regexp = novi StringBuilder (); for (Riječ u nizu: riječi) {regexp.append ("(? =. *"). append (word) .append (")"); }

Nakon toga koristit ćemo podudaranje () metoda za pronaći() pojave:

javna statička logička vrijednost sadržiWordsPatternMatch (String inputString, String [] riječi) {StringBuilder regexp = novi StringBuilder (); for (Riječ u nizu: riječi) {regexp.append ("(? =. *"). append (word) .append (")"); } Uzorak uzorka = obrazac.compile (regexp.toString ()); vrati obrazac.matcher (inputString) .find (); }

Ali, regularni izrazi imaju cijenu izvedbe. Ako moramo potražiti više riječi, izvedba ovog rješenja možda neće biti optimalna.

6. Korištenje Java 8 i Popis

I na kraju, možemo koristiti Stream API Java 8. Ali prvo, napravimo neke manje transformacije s našim početnim podacima:

Popis inputString = Arrays.asList (inputString.split ("")); Riječi na popisu = Arrays.asList (riječi);

Sada je vrijeme da upotrijebimo Stream API:

javni statički boolean sadržiWordsJava8 (String inputString, String [] riječi) {List inputStringList = Arrays.asList (inputString.split ("")); Popis wordsList = Arrays.asList (riječi); vratiti wordsList.stream (). allMatch (inputStringList :: sadrži); }

Gornji operativni cjevovod vratit će se pravi ako ulazni niz sadrži sve naše ključne riječi.

Alternativno, možemo jednostavno koristiti sadržiSve () metoda okvira Zbirke za postizanje željenog rezultata:

javni statički boolean sadržiWordsArray (String inputString, String [] riječi) {List inputStringList = Arrays.asList (inputString.split ("")); Popis wordsList = Arrays.asList (riječi); vrati inputStringList.containsAll (wordsList); }

Međutim, ova metoda djeluje samo za cijele riječi. Dakle, naše bi ključne riječi pronašao samo ako su odvojene razmacima unutar teksta.

7. Korištenje Aho-Corasick Algoritam

Jednostavno rečeno, Aho-Corasick algoritam je za pretraživanje teksta s više ključnih riječi. Ima Na) vremenska složenost bez obzira na to koliko ključnih riječi tražimo ili koliko je duga duljina teksta.

Uključimo ovisnost Aho-Corasickovog algoritma u naš pom.xml:

 org.ahocorasick ahocorasick 0.4.0 

Prvo, izgradimo trie cjevovod s riječi niz ključnih riječi. Za to ćemo upotrijebiti strukturu podataka Trie:

Trie trie = Trie.builder (). OnlyWholeWords (). AddKeywords (words) .build ();

Nakon toga, nazovimo metodu parsera s inputString tekst u kojem bismo željeli pronaći ključne riječi i spremiti rezultate u emitira kolekcija:

Zbirka emits = trie.parseText (inputString);

I na kraju, ako ispisujemo naše rezultate:

emits.forEach (System.out :: println);

Za svaku ćemo ključnu riječ u tekstu vidjeti početni položaj ključne riječi, završni položaj i samu ključnu riječ:

0: 4 = pozdrav 13:20 = Baeldung

Na kraju, pogledajmo kompletnu implementaciju:

javna statička logička vrijednost sadržiWordsAhoCorasick (String inputString, String [] riječi) {Trie trie = Trie.builder (). onlyWholeWords (). addKeywords (words) .build (); Zbirka emits = trie.parseText (inputString); emits.forEach (System.out :: println); logička vrijednost pronađena = točno; for (String word: words) {boolean contains = Arrays.toString (emits.toArray ()). contains (word); if (! sadrži) {pronađeno = netačno; pauza; }} povratak pronađen; }

U ovom primjeru tražimo samo cijele riječi. Dakle, ako želimo podudarati ne samo inputString ali "ZdravoBaeldung" također bismo trebali jednostavno ukloniti onlyWholeWords () atribut iz Trie graditelj cjevovod.

Uz to, imajte na umu da uklanjamo i ponovljene elemente iz emitira zbirke, jer za istu ključnu riječ može postojati više podudaranja.

8. Zaključak

U ovom smo članku naučili kako pronaći više ključnih riječi unutar niza. Štoviše, pokazali smo primjere pomoću jezgre JDK, kao i sa Aho-Corasick knjižnica.

Kao i obično, cjeloviti kôd za ovaj članak dostupan je na GitHubu.