Reputation: 23
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
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
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
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