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.
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
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! ");
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.
Related
I have been trying to create a program in Java that outputs each word found in a string and the number of times they appear. I have been trying to do this without using any arrays or hashmap, and by only using string manipulation methods and string tokenizer, but I can't seem to wrap my head around the logic.
Here is what I have so far.
Scanner sc=new Scanner(System.in);
String input="";
int count=1;
String word="";
System.out.println("Enter your paragraph.");
input=sc.nextLine();
StringTokenizer st=new StringTokenizer(input);
while(st.hasMoreTokens()){
word=st.nextToken();
while(st.hasMoreTokens()){
if(st.nextToken()==word){
count++;
}
}
System.out.println(word+": "+count);
input=input.replaceAll(currentToken," ")
count=1
}
The output I am currently receiving is (the first word entered)=0.
Any help or advice with this or anything to lead me in the right direction?
You are quite close. But the 0 as result does not match your posted code, it is 1, but even if there are more occurrences. That is because you used == instead of .equals() in the if.
And in the end of the loop the tokenizer has been drained by the inner loop, so you should reinitialize a new one, espacially after you already changed the input string.
StringTokenizer st = new StringTokenizer(input);
while (st.hasMoreTokens()) {
word = st.nextToken();
while (st.hasMoreTokens()) {
if (st.nextToken().equals(word)) {
count++;
}
}
System.out.println(word + ": " + count);
input = input.replaceAll(word, "");
count = 1;
st = new StringTokenizer(input);
}
Note: As Andreas and coolioasjulio mentioned is the use of StringTokenizer discouraged (more about it here).
I am just starting out in Java so I appreciate your patience. Anyways, I am writing a word count program as you can tell by the title, I am stuck at the numWords function below the for loop, I am not sure what I should set it equal to. If someone could set me in the right direction that would be awesome. Thank you. Here is all of my code thus far, let me know if I not specific enough in what I am asking, this is my first post. Thanks again.
import java.util.Scanner;
public class WCount {
public static void main (String[] args) {
Scanner stdin = new Scanner(System.in);
String [] wordArray = new String [10000];
int [] wordCount = new int [10000];
int numWords = 0;
while(stdin.hasNextLine()){
String s = stdin.nextLine();
String [] words = s.replaceAll("[^a-zA-Z ]", "").toLowerCase().split("\\s\
+");
for(int i = 0; i < words.length; i++){
numWords = 0;
}
}
}
}
If your code is intended to just count words, then you don't need to iterate through the words array at all. In other words, replace your for loop with just:
numWords += words.length;
Most likely a simpler approach would be to look for sequences of alpha characters:
Matcher wordMatch = Pattern.compile("\\w+").matcher();
while (wordMatch.find())
numWords++;
If you need to do something with the words (such as store them in a map to a count) then this approach will make that simpler:
Map<String,Integer> wordCount = new HashMap<>();
Matcher wordMatch = Pattern.compile("\\w+").matcher();
while (wordMatch.find()) {
String word = wordMatch.group();
int count = wordCount.getOrDefault(word, 0);
wordCount.put(word, count + 1);
}
Don't worry. We were all beginners once.
First of all, you don't need to do the loop because "length" attribute already has it. But, if you want to practice with loops is so easy as increasing the counter each time the iterator advances and that's it.
numWords++;
Hint: Read the input
String sentence = stdin.nextLine();
Split the string
String [] words = sentence.split(" ");
Number of words in a sentence
System.out.println("number of words in a sentence are " + words.length);
You mentioned in comments that you would also like to print the line in alphabetical order. For that Java got you covered:
Arrays.sort(words);
The best way to count the amount of words in a String String phrase is simply to get a String array from it using the String method split String[] words = phrase.split(" ") and giving it as argument the space itself, this will return a String array with each different words, then you can simple check its lengthwords.length and this will give you the exact number.
Hello I am working on an assignment and I'm running into issues I was hoping for a little direction...
The purpose is to have user input a phrase and create an acronym out of that phrase. Anything over three words will be ignored.
I'm having issues with the acronym part, I am able to get the first character and figured that I would loop through the user input and grab the character after a space, but that is not working. All I am getting is the first character, which is obvious because I grab that first, but I can't figure out how to "save" the other two characters. Any help is greatly appreciated.
*********UPDATE************************
So thanks to an answer below I have made progress with using the StringBuilder. But, now if I enter "Your Three Words" the Output is: YYYYYTYYYYYWYYYY
Which is progress but I can't understand why it's repeating those first characters so many times??
I edited the code too.
*********UPDATE*****************************
public class ThreeLetterAcronym {
public static void main(String[] args) {
String threeWords;
StringBuilder acronym = new StringBuilder();
Scanner scan = new Scanner(System.in);
System.out.println("Enter your three words: ");
threeWords = scan.nextLine();
for(int count = 0; count < threeWords.length(); count++) {
acronym.append(threeWords.charAt(0));
if(threeWords.charAt(count) == ' ') {
++count;
acronym.append(threeWords.charAt(count));
}
}
System.out.println("The acronym of the three words you entered is: " + acronym);
}
}
You can't save the other characters because char is supposed to store only one character.
You can use a StringBuilder in this case
StringBuilder acronym = new StringBuilder();
Then in your loop simply replace it with
String[] threeWordsArray = threeWords.split(" ");
for(String word : threeWordsArray) {
acronym.append( word.substring(0, 1) );
}
**updated
You store the character at the current index in space:
char space = threeWords.charAt(count);
Then you compare the value of space with the integer value 3:
if(space < 3)
This will almost certainly never be true. You are asking for the numeric value of a character. Assuming it is a letter it will be at least 65. I suspect that your intention is to store something different in the variable space.
I have a string array
String a = "This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty.";
String a1[]=a.split(" ");
for(String temp: a1)
{
System.out.println(temp);
}
Here "life" is repeated three times. Now I have to remove only one frequency of duplicate word form array.
please guide me....
Thanks.
You can use something like this, but this will remove only first occurence of specified word:
Full code which removes one duplicate. You need to know that it doesn't ignore special characters, and space is delimiter in this case.
public static void main(String []args){
String a = "This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty Mitty";
System.out.println(removeOneDuplicate(a));
}
public static String removeOneWord(String str, String word){
int value = str.indexOf(word);
String result = str.substring(0, value);
result += str.substring( value+word.length(), str.length());
return result;
}
public static String removeOneDuplicate(String a){
String [] tmp = a.split(" ");
Map<String, Integer> map = new HashMap<String, Integer>();
for(String s: tmp){
if( map.containsKey(s)){
int value = map.get(s);
if(value == 1)
a = removeOneWord(a, s);
map.put(s, value + 1);
}
else
map.put(s, 1);
}
return a;
}
Sample results:
INPUT: This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty Mitty
OUTPUT: This is a and our life will be full fun just like the Benn Steller's Secret life of Walter Mitty
In result You can see that life, of and Mitty is removed.
EDIT
If you want to remove all duplicates and leave first occurence of word change following lines:
int value = str.indexOf(word); -> int value = str.lastIndexOf(word);
int value = map.get(s);
if(value == 1)
a = removeOneWord(a, s);
map.put(s, value + 1);
to:
a = removeOneWord(a, s);
First of all, the example you provided is not a String array. It is a String.
I am giving the solution based on String. If you need it for String array, you will be able to do this on your own, if you understand this.
First, lets take a string tokenizer. A tokenizer breaks apart a string by a given character set. In its simplest form, it breaks apart a string by space.
For example, a string str = "This is a test". A simple tokenizer will break this string into words like "This" "is" "a" "test".
Below is the code to declare and use tokenizer:
StringTokenizer st = new StringTokenizer(a); // a is given your string
Now, we declare an array of string below. (An array of string is an array, the element of each array is a single string.)
String[] str_arr = new String[100];
We will now use the tokenizer to get each word of your string and keep each words in the array of strings like below:
int index=0; // to keep track of index of the array (of strings)
while (st.hasMoreElements()) {
str_arr[index] = (String) st.nextElement();
index++;
}
So, now we have an array of strings named 'str_arr'. Now we will check for each element of the array whether duplicate values are occuring or not. If we find a duplicate, we will replace it with a null value. But, we will do it only once. The remaining duplicates will be kept as it is, this is what you asked for, right?
To keep track of a string already searched and made null, we will use a HashMap like this.
HashMap<String, Integer> hash_map = new HashMap<String, Integer>();
Now, we will run 2 nested loops and after that, we will have a modified array where only multiple occurrence of a string is reduced by 1.
for(int i=0; i<index; i++){
String current_string = str_arr[i];
for(int j=i+1; j<index; j++){
if( (current_string.equals(str_arr[j])) && (hash_map.containsKey(current_string)==false) && str_arr[j]!=""){
hash_map.put(str_arr[j], 1);
str_arr[j]="";
break;
}
}
}
Now, you can print all the words simply as below:
for(int i=0; i<index; i++)
System.out.print(str_arr[i]+" ");
INPUT: This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty.
OUTPUT: This is a life and our will be full of fun just like the Benn Steller's Secret life Walter Mitty.
Sorry for long explanation, but still if you can't get any point, please comment. I will try to reply.
Thanks!
Happy Coding :)
As we know, set does not contain duplicate at all.
My Code:
String a = "This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty.";
String[] aSpilt = a.split(" ");
List<String> list = Arrays.asList(aSpilt);
System.out.print("The input is : ");
list.forEach((s) -> System.out.print(s + " "));
System.out.println();
Set<String> noDuplicateSet = new LinkedHashSet<>();
Set<String> duplicateSet = new LinkedHashSet<>();
list.forEach((i) -> {
if (!noDuplicateSet.add(i) && i.equals("life")) {
duplicateSet.add(i + " ");
}
});
System.out.print("The output is : ");
noDuplicateSet.forEach((s) -> System.out.print(s + " "));
System.out.println("");
duplicateSet.forEach((s) -> System.out.print(s + " "));
My output:
The input is : This is a life and our life will be full of fun just like the Benn Steller's Secret life of Walter Mitty.
The output is : This is a life and our will be full of fun just like the Benn Steller's Secret Walter Mitty
Note:
I kept the first life and remove the rest, and of was encountered more than once which I did not touched because the question wants just to keep first life and remove the rest.
I used lambda expression to traverse collections
Sources:
http://www.programcreek.com/2013/03/hashset-vs-treeset-vs-linkedhashset/
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
public static void main(String args[])
{
String s;
Scanner in=new Scanner(System.in);
s=in.nextLine();
String ch[]=s.split(" ");
String m=in.nextLine();
for(int i=;i<ch.length;i++)
{
if(ch[i].matches(m))
ch[i]="";
S.o.p(ch[i]);
}
}
I am trying to take in words from a file input that only contains strings and store each word separately into a single array (ArrayList is not allowed).
My code below takes in the file input, but takes it in as one chunk. For example, if the file input was "ONE TWO THREE" I want each word to have its own index in the array (array[0] = "ONE", array[1]="TWO" and array[2]="THREE") but my code below just takes the sentence and puts it all in array[0] = "ONE TWO THREE". How can I fix this?
int i = 0;
String wd = "";
while (in.hasNextLine() ) {
wd = in.nextLine() ;
array[i] = wd;
i++;
System.out.println("wd");
}
Thats happens because you a reading LINES from the file. You can do something like this:
String array[]=in.nextLine().split(" ");
f the file input was " ONE TWO THREE" i want each word to have its own
space in the array so array[0] = ONE, array1=TWO and array[2]=THREE
Use String#split(delim) with white space as delimiter.
String fileInput = "ONE TWO THREE";
String[] array = filrInput.split("\\s");
Instead of the line
array[i] = wd; // since wd is the whole line, this puts lines in the array
you want to split the line you read in and put the split items in your array.
String[] items = wd.split("\\s+"); // splits on any whitespace
for (String item : items) { // iterate through the items and shove them in the array
array[i] = item;
i++;
}
I would set the delimiter to space " " then use .next().
in.useDelimiter(" ");
while(in.hasNext()){
wd = in.next();
//wd will be one word
}