Jestem całkiem nowy w Javie i obecnie utknąłem i nie wiem, jak postępować.

Chcę tylko sprawdzić, czy ciąg zawiera jakieś słowa z listy słów, a jeśli tak, to wypisać je.

W moim przypadku wszystkie ciągi będą miały podobny tekst, jak ten (przykład z 5 minutami):

Set timer to five minutes

Albo ten:

Timer five minutes

To jest mój obecny kod z kilkoma komentarzami, co próbuję zrobić:

import java.util.stream.Stream; 

class GFG { 

// Driver code 
public static void main(String[] args) 
{ 

String example = Set timer to five minutes

    Stream<String> stream = Stream.of(("Timer", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten") //The stream/array would be much bigger since I want to cover every number till 200 

//Now I thought I can use stream filter to check if example contains the word Timer and any of the words of the Stream and if it does I want to use the output to trigger something else

    if(stream.filter(example -> example .contains(NOTSUREWHATTOPUTHERE))) {
       //If detected that String contains Timer and Number, then create timer 
    } 
} 

Czy ktoś może mi udzielić porady / pomocy?

Pozdrowienia

1
Salexes 19 listopad 2019, 20:12
1
Co się stanie, jeśli ciąg wejściowy to „Śpiewaj przez dwie minuty”?
 – 
Naman
19 listopad 2019, 20:38
1
Dobre pytanie, więc najlepiej byłoby również upewnić się, że słowo Timer jest tam zdecydowanie. Powinienem był o tym wspomnieć w moim pytaniu.
 – 
Salexes
19 listopad 2019, 20:46
1
Innym podejściem może być utworzenie @Builder class Action { String type; String value; } używanego dalej w String example = "Set timer to five minutes"; Set<String> words = Arrays.stream(example.split(" ")).collect(Collectors.toSet()); Set<String> actions = Set.of("Timer", "Music"); Set<String> values = Set.of("One", "Two", "Three",...); Action.ActionBuilder actionBuilder = Action.builder(); actions.stream().filter(words::contains).findFirst().ifPresent(s -> { actionBuilder.type(s); values.stream().filter(words::contains).findFirst().ifPresent(actionBuilder::value); });//Use action further }.
 – 
Naman
19 listopad 2019, 21:00
Czy mógłbyś to opublikować jako odpowiedź, wydaje się, że sekcja komentarzy utrudnia czytanie kodu.
 – 
Salexes
19 listopad 2019, 21:01

1 odpowiedź

Możesz to zrobić w ten sposób:

String[] words = { "Timer", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" };

String example = "Set timer to five minutes";

String exLower = example.toLowerCase();
if (Stream.of(words).anyMatch(word -> exLower.contains(word.toLowerCase()))) {
    //
}

Ten kod przynajmniej sprawdzi się poprawnie, nawet jeśli słowa mają różne duże / małe litery, ale nie powiedzie się, jeśli tekst zawiera słowo osadzone w innym słowie, np. tekst "stone" będzie pasował, ponieważ znaleziono "one".

Aby to naprawić, „najłatwiej” byłoby przekonwertować listę słów na wyrażenie regularne.

String[] words = { "Timer", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten" };

String example = "Set timer to five minutes";

String regex = Stream.of(words).map(Pattern::quote)
        .collect(Collectors.joining("|", "(?i)\\b(?:", ")\\b"));
if (Pattern.compile(regex).matcher(example).find()) {
    //
}
3
Andreas 19 listopad 2019, 20:38
Bez wchodzenia w parsowanie ciągów i wykrywanie wzorców, które same w sobie są dość szerokie. Ale dlaczego nie użyć split i nie zebrać słów toSet, a następnie wykonać zawiera dla któregokolwiek z nich pod podanym list?
 – 
Naman
19 listopad 2019, 20:43
Dziękuję Ci za to. Mam jeszcze jedno pytanie. Słowo Timer musi znajdować się w ciągu, a jedna z cyfr jako słowo. Jak mogę się upewnić, że przypadek if jest uruchamiany tylko wtedy, gdy zawiera licznik czasu i liczbę?
 – 
Salexes
19 listopad 2019, 20:45
Wyczuwałem, że przybycie stąd było pytaniem w komentarzu do pytania. Co się stanie, jeśli na wejściu pojawi się „Śpiewaj przez dwie minuty”? Jak zachowuje się aplikacja?
 – 
Naman
19 listopad 2019, 20:46
1
Wykonaj test dwa razy, raz z Timer jako jedynym słowem na liście i raz ze wszystkimi liczbami na liście słów.
 – 
Andreas
19 listopad 2019, 20:46
Musi również zawierać słowo Timer. Powinienem był o tym wspomnieć w moim pytaniu.
 – 
Salexes
19 listopad 2019, 20:49