Bashar
Bashar

Reputation: 23

Check if String contains multiple values stored in Array of strings

I'm trying to write a program that checks if a string contains multiple words that must be occurred in a specific order the words are stored in Array of Strings

Here what I have reached so far

boolean Check = false;
Scanner S = new Scanner(System.in);            

System.out.println("What is your question?");
String input=S.nextLine();

String[] Words = {"pay","car"};

for (int i = 0; i <= Words.length -1  ; i++) {

    if (input.matches(".*\\b"+Words[i]+"\\b.*") && input.matches(".*\\b"+Words[1]+"\\b.*")) {
         Check = true;
    }
}
if (Check){
    System.out.println("30k Dollar");
} else{
    System.out.println("Wrong info! ");
}

Basically, what my code does is when the user input for example "how much should i pay for the car?" he will get an answer of "30k Dollar"

because the strings "pay" and "car" are both in my array of strings.

Case 2: if the user input " bla bla car bla bla pay"

he will get the same answer.

How can I prevent the program from giving the same answer for the 2 different questions?

also in my code I used Words[i] and Words[1] but when I got larger list of words this wont work, I tried using nested loop but it didn't work.

Upvotes: 1

Views: 3137

Answers (3)

Justin Ryder
Justin Ryder

Reputation: 777

You could combine them into a single regex check. You're already matching any character before or after (with .*) so just basically concatenate your regex strings into a single check.

if (input.matches(".*\\b" + Words[0] + "\\b.*\\b" + Words[1] + "\\b.*"))

EDIT: response to "also in my code I used Words[i] and Words[1] but when I got larger list of words this wont work, I tried using nested loop but it didn't work."

You could just iterate over the input words to create the regex string. String regexPattern = ".*\\b" + String.Join("\\b.*\\b", Words) + "\\b.*";

EDIT2: here's my answer and edit combined w/ more context in the code:

String[] Words = {"pay","car"};
String regexPattern = ".*\\b" + String.Join("\\b.*\\b", Words) + "\\b.*";

if (input.matches(regexPattern)) {
  System.out.println("30k Dollar");
} else {
  System.out.println("Wrong info!");
}

EDIT3: Replaced Words.Join() with String.Join() cause I can Java w/o a compiler, real gud.

Upvotes: 0

Amer Qarabsa
Amer Qarabsa

Reputation: 6574

I will assume you always look for words separated by spaces, so you can get the words separated using split

String inputWords[] = input.split(" ");

First thing we need to reduce the time complexity of checking if the word is in our array so we can fill the array in a set but since we care about the order we better use a map with key the word and value the index of that word in the array

Map<String,Integer> map = new HashMap<>();
String[] words = {"pay","car"};
for(int i =0; i< words.length; i++)
        map.put(words[i], i);

So now all you need is to iterate over your inputWords and check that all the words are there and you are not violating the order, this time complexity is O(n)

int lastFoundIndex = -1;
int numFound =0;
for(int i=0; i < inputWords.length; i++) {

if(map.get(inputWords[i]) != null ) {
    if(map.get(inputWords[i]) < lastFoundIndex)
       break;
     lastFoundIndex = map.get(inputWords[i]);
      numFound ++;
}
}
if(numFound  >= words.length) // this condition means we are allowing more than occurence without violating the order

     system.out.println("30k Dollar");

else 
     System.out.println("Wrong info! ");

Upvotes: 0

Oneiros
Oneiros

Reputation: 4378

You don't need to iterate over input words, just generate the full regex:

String[] words = {"pay","car"};
String regex = ".*\\b" + String.join("\\b.*\\b", words) + "\\b.*";

String test1= "how much should i pay for the car?";
System.out.println(test1.matches(regex)); // True

String test2 = "bla bla car bla bla pay";
System.out.println(test2.matches(regex)); // False

Upvotes: 1

Related Questions