Teller ord i en streng med Java

1. Oversikt

I denne opplæringen skal vi gå over forskjellige måter å telle ord i en gitt streng bruker Java.

2. Bruke StringTokenizer

En enkel måte å telle ord på i en streng i Java er å bruke StringTokenizer klasse:

assertEquals (3, nye StringTokenizer ("tre blinde mus"). countTokens ()); assertEquals (4, ny StringTokenizer ("se \ thow \ tthey \ trun"). countTokens ());

Noter det StringTokenizer tar automatisk ta vare på hvitt rom for oss, som tapper og vognreturer.

Men det kan gå opp noen steder, som bindestreker:

assertEquals (7, nye StringTokenizer ("bondekona - hun var fra Albuquerque"). countTokens ());

I dette tilfellet vil vi at "kone" og "hun" skal være forskjellige ord, men siden det ikke er noe mellomrom mellom dem, mislykkes standardinnstillingene.

Heldigvis, StringTokenizer sendes med en annen konstruktør. Vi kan passere en avgrenser inn i konstruktøren for å få ovennevnte til å fungere:

assertEquals (7, ny StringTokenizer ("bondekona - hun var fra Albuquerque", "-"). countTokens ());

Dette kommer godt med når du prøver å telle ordene i en streng fra noe som en CSV-fil:

assertEquals (10, ny StringTokenizer ("gjorde, du, noensinne, se, slik, en, syn, i, ditt, liv", ","). countTokens ());

Så, StringTokenizer er enkelt, og det får oss mesteparten av veien dit.

La oss se om hvilke ekstra hestekrefter regulære uttrykk kan gi oss.

3. Vanlige uttrykk

For at vi skal komme med et meningsfullt regulært uttrykk for denne oppgaven, må vi definere hva vi anser som et ord: et ord starter med en bokstav og slutter enten med et mellomromstegn eller et skilletegn.

Med dette i bakhodet, gitt en streng, er det vi ønsker å gjøre å dele den strengen på hvert punkt vi møter mellomrom og skilletegn, og deretter telle de resulterende ordene.

assertEquals (7, countWordsUsingRegex ("bondekona - hun var fra Albuquerque"));

La oss skru opp ting litt for å se kraften til regex:

assertEquals (9, countWordsUsingRegex ("ingen & # skal% alltid skrive-lignende, dette; men: vel"));

Det er ikke praktisk å løse denne gjennom å bare sende en avgrenser til StringTokenizer siden vi måtte definere en veldig lang skillelinje for å prøve å liste opp alle mulige skilletegn.

Det viser seg at vi virkelig ikke trenger å gjøre mye, passerer regex[\ pP \ s && [^ ']] +tildelemetoden forStringklassen vil gjøre susen:

offentlig statisk int countWordsUsingRegex (String arg) {if (arg == null) {return 0; } siste streng [] ord = arg.split ("[\ pP \ s && [^ ']] +"); returord. lengde; }

Regex [\ pP \ s && [^ ']] + finner en hvilken som helst lengde på enten tegnsettingstegn eller mellomrom og ignorerer apostroftegnsettingstegnet.

For å finne ut mer om vanlige uttrykk, se Regulære uttrykk på Baeldung.

4. Sløyfer og String API

Den andre metoden er å ha et flagg som holder orden på ordene som har blitt møtt.

Vi setter flagget til ORD når du møter på et nytt ord og øker ordtellingen, og deretter tilbake til SEPARATOR når vi møter et ikke-ord (tegnsetting eller mellomromstegn).

Denne tilnærmingen gir oss de samme resultatene vi fikk med vanlige uttrykk:

assertEquals (9, countWordsManually ("ingen & # skal% alltid skrive-lignende, dette men vel")); 

Vi må være forsiktige med spesielle tilfeller der skilletegn ikke er ordskillere, for eksempel:

assertEquals (6, countWordsManually ("bondekona - hun var fra Albuquerque"));

Det vi ønsker her er å telle "bondens" som ett ord, selv om apostrofen "'" er et tegnsettingstegn.

I regex-versjonen hadde vi fleksibiliteten til å definere hva som ikke kvalifiserer som et tegn ved hjelp av regex. Men nå som vi skriver vår egen implementering, vi må definere denne eksklusjonen i en egen metode:

private static boolean isAllowedInWord (char charAt) 

Så det vi har gjort her er å tillate i et ord alle tegn og juridiske skilletegn, apostrofen i dette tilfellet.

Vi kan nå bruke denne metoden i implementeringen:

offentlig statisk intellingWordsManually (String arg) {if (arg == null) {return 0; } int flag = SEPARATOR; int-antall = 0; int stringLength = arg.length (); int characterCounter = 0; mens (characterCounter <stringLength) {if (isAllowedInWord (arg.charAt (characterCounter)) && flag == SEPARATOR) {flag = WORD; telle ++; } annet hvis (! isAllowedInWord (arg.charAt (characterCounter))) {flag = SEPARATOR; } karakterTeller ++; } returantall; }

Den første tilstanden markerer et ord når det møter ett, og øker telleren. Den andre tilstanden sjekker om tegnet ikke er en bokstav, og setter flagget til SEPARATOR.

5. Konklusjon

I denne opplæringen har vi sett på måter å telle ord ved å bruke flere tilnærminger. Vi kan velge hvilke som helst, avhengig av vårt spesielle bruksområde.

Som vanlig kan kildekoden for denne opplæringen bli funnet på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found