I want to split a string into parts of 3 words in Java.
For example:
I want to walk in the park with my father
I want to have a string: "I want to", and another string:"walk in the", etc.
How would I do this?
Here is a solution using RegEx
String sentence = "I want to walk in the park with my father";
Pattern pattern = Pattern.compile("\\w+ \\w+ \\w+ ");
Matcher matcher = pattern.matcher(sentence);
while (matcher.find()) {
System.out.println(matcher.group());
}
Notice that whit this expression the last word 'father' is not matched.
For the non-RegEx solution, I would use something like this
String sentence = "I want to walk in the park with my father";
String[] words = sentence.split(" ");
List<String> threeWords = new ArrayList<>();
int length = words.length;
for (int ind = 2; ind < length; ind += 3) {
threeWords.add(words[ind - 2] + " " + words[ind - 1] + " " + words[ind]);
}
if (length % 3 == 1) {
threeWords.add(words[length - 1]);
} else if (length % 3 == 2) {
threeWords.add(words[length - 2] + " " + words[length - 1]);
}
For me creating a temporary ArrayList (aka words), and removing 3 words at a time, concatenating them into a String, and adding it to my final ArrayList worked just fine, although this probably isn't extremely performance efficient, it gets the job done & it's simple to understand.
// finalWords is your result
ArrayList<String> finalWords = new ArrayList<String>();
ArrayList<String> words = new ArrayList<String>();
for(String str : "I want to walk in the park with my father".split(" "))
words.add(str);
while(words.size() > 0)
{
String str = "";
for(int i = 0; i < 3; i++)
{
if(words.size() > 0)
{
str += words.get(0) + " ";
words.remove(0);
}
}
finalWords.add(str);
}
EDIT: Since you wrote this:
I know how to split it in individual words, but not into groups.
in the comments, splitting it into groups of words is simple. First, you split your sentence into words, then you concatenate those words into new strings, 3 at a time, and add the concatenated strings to a list/array of your choice.
Related
I want to find the characters of the second word in a phrase using indexOf(); method and charAt();
You have to assume that the phrase will always have 3 words and that the second words will always have 5 letters.
Sample input is "The white horse" ------> output is: Second word is 'white'
I have to achieve this without loops, built-in methods of java like substring, split...etc
Here is my attempt but it keeps giving me one character:
It should be constant that means it should always be 5, I think its the use of a print statement 5 times
else if (option == 4){
int start = phrase.indexOf(' ');
int end = phrase.indexOf(' ', start + 1);
int length = end - start - 1;
char n = phrase.charAt(length+2);
System.out.print("Second word is '"+n+"'");
}
Quoting the requirements, and highlighting the important ones:
Find the characters of the second word in a phrase using indexOf() method and charAt(). You have to assume that the phrase will always have 3 words and that the second word will always have 5 letters.
Can't use substring or any loops.
Seems you have to do it like this:
String phrase = "The white horse";
int idx = phrase.indexOf(' ');
System.out.println("Second word is '" + phrase.charAt(idx + 1)
+ phrase.charAt(idx + 2)
+ phrase.charAt(idx + 3)
+ phrase.charAt(idx + 4)
+ phrase.charAt(idx + 5) + "'");
Or like this:
String phrase = "The white horse";
int idx = phrase.indexOf(' ');
System.out.print("Second word is '");
System.out.print(phrase.charAt(idx + 1));
System.out.print(phrase.charAt(idx + 2));
System.out.print(phrase.charAt(idx + 3));
System.out.print(phrase.charAt(idx + 4));
System.out.print(phrase.charAt(idx + 5));
System.out.println("'");
Simple solution:
String[] words = phrase.split(" ");
System.out.print("Second word is '"+words[1]+"'");
Solution using only charAt() and indexOf()
int start = phrase.indexOf(' ');
int end = phrase.indexOf(' ', start + 1);
System.out.print("Second word is '");
for (int i=start+1; i<end; i++) {
System.out.print(phrase.charAt(i));
}
System.out.print("'");
use this to achieve the second word :
final String ans = input.split(" ")[1];
or try repeating your code 5 times with icreasing your index.
I have a string:
String text = "Nothing right in my brain. Nothing left in my brain"
I want to create a new string text2 that has 2-4 random new line from previous, such as:
"Nothing \n right \n in my brain. \n Nothing left in my brain"
or
"Nothing right in \n my brain. Nothing left in \n my brain"
How to create a new string with random new line between the words?
I am thinking to get the index of whitespace, in order to insert new line after random whitespace. But I only keep getting the first whitespace index.
Anyone know better approach to solve this? Thank you.
There are three stages to your problem, splitting the String, inserting randomness and using them together...
Splitting a String
Break it into words with String.split(), which creates an array of Strings (in this case words) by spaces.
String[] words = text.split(" "); //Split by spaces
then rebuild your String with newlines added for instance:-
StringBuiler sb = new StringBuilder();
for (String word : words)
{
sb.append(word + "\n");
}
String text2 = sb.toString();
In this case you will insert a newline in between every word and save the result in text2.
Inserting Randomness
You could just create a Random object...
Random random = new Random();
Then use it in the code that inserts your newline, like so...
//Randomly add or don't add a newline (Compacted with a ternary operator instead of an 'if')
sb.append(word + (random.nextBoolean() ? "\n" : ""));
Bringing it together (TLDR)
Then all you need to do is maintain a count of inserted newlines and limit them to that. So your code becomes:-
int requiredNewlines = random.nextInt(2 - 5) + 2; //Number between 2-4
for (String word : words) //For each word
{
sb.append(word); //Add it
if (requiredNewlines >= 0 && random.nextBoolean())
{
//Randomly add newline if we haven't used too many
sb.append("\n");
requiredNewlines--;
}
}
String text2 = sbAppen.toString();
Additionally
Although the randomness in this example fits your purpose here it is not the ideal implementation of random (as mentioned in the comments), in that there is more bias towards one appearing nearer the start of the String than the end and that there no chance of it appearing before the first word.
There is also another option of using StringTokenizer instead of String.split() which I much prefer but it doesn't deal with regex and is falling out of use, so I've changed my answer to use String.split()
First you need a new random from 2-4:
int max = 4;
int min = 2;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
After split string into words:
String[] words = text.split(" ");
Then, get 4 different numbers from 1 to words.length
ArrayList<Integer> randomPositions = new ArrayList<Integer>(randomNum);
max = words.length;
min = 1;
for (int count = 0; count < randomNum; count ++) {
int random = rand.nextInt((max - min) + 1) + min;
if (randomPositions.contains(random)) count --;
else randomPositions.add(random);
}
Finally put \n in positions when rebuilding the array:
StringBuilder result = new StringBuilder();
for (int count = 0; count < max; count ++) {
result.append(words[count]);
if (randomPositions.contains(count))
result.append("\n");
else
result.append(" ");
}
Check this working demo
Output1:
Nothing right in my
brain. Nothing
left in my brain
Output2:
Nothing right
in my brain. Nothing left
in my
brain
Output3:
Nothing right in my brain. Nothing left
in my brain
You can only get either the first index using indexOf() or the last index using lastIndexOf() methods.
But as a workaround you can use text.indexOf(" ", randomInt);. This will give you the first index of " " after the randomInt index.
String str = "Nothing right in my brain. Nothing left in my brain";
String[] split = str.split(" ");
for (int i = 0; i < split.length; i++) {
int flag = ((int) (Math.random() * 10)) % 2;
if (flag == 0) {
split[i] = split[i] + "\n";
}
}
str="";
for (int i = 0; i < split.length; i++) {
str += split[i]+" ";
}
First you could get a random index where to put the new line
Random rand = new Random();
String[] words = text.split(' ');
for(int i = 0; i < 3; i++){
int index = rand.nextInt(words.length());
words[index] = "\n" + words[index];
}
text = Arrays.toString(words);
and at the end you will have 3 new lines on random places in your text string
EDIT: one way the result to be without commas is this one:
text = Arrays.toString(words).replaceAll(", ", " ");
Generate String with insertions at different positions:
public static String generateString(String inputString, String delimiter,
String insString, int[] insIndexes) {
String[] splittedString = inputString.split(delimiter);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < splittedString.length; i++) {
sb.append(splittedString[i]);
if (Arrays.binarySearch(insIndexes, i + 1) >= 0)
sb.append(delimiter + insString);
sb.append(delimiter);
}
return sb.toString();
}
Invocation Part :
String inputString = "Nothing right in my brain. Nothing left in my brain";
String delimiter = " "; // input String delimiter
String insString = "\n"; // insertion String
int[] insIndexes = { 2, 4, 6, 8 }; // insertion indexes
String outputString = generateString(inputString, delimiter, insString, insIndexes);
This is my code to work out the length of a word:
public class WordCount {
public static void main (String args []) {
String text;
text = "Java";
System.out.println (text);
//Work out the length
String [] input = text.split(" ");
int MaxWordLength = 0;
int WordLength = 0;
for (int i = 0; i < input.length; i++)
{
MaxWordLength = input[i].length();
WordLength = MaxWordLength;
} //End of working out length
//Work out no. of words
int[] intWordCount = new int[WordLength + 1];
for(int i = 0; i < input.length; i++) {
intWordCount[input[i].length()]++; }
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
}
}
}
The problem I am having is that when it prints out the length of the word, I get these results:
Java
There are 0 words of length 4
There are 0 words of length 4
There are 0 words of length 4
There are 1 words of length 4
But when I change the text to "J" this prints out:
J
There are 1 words of length 1
Any idea why it's doing that?
P.S. I'm kind of new to Java and any help would be appreciated.
I am not sure if you want to count letter or word because your code counts letter to me.
Just you need to change this line from
String [] input = text.split(" ");
to
String [] input = text.split("");
and your program works perfectly.
input: Java
output: There are 4 letters of length 1 <- Hope this is the expected result for you
Source: Splitting words into letters in Java
You can achieve this in better and less headache by using Lambda in Java
Code:
import java.util.*;
public class LambdaTest
{
public static void main (String[] args)
{
String[] st = "Hello".split("");
Collection myList = Arrays.asList(st);
System.out.println("your word has " + myList.stream().count() + "letters");
}
}
Output:
your word has 5 letters CLEARLY in length 1
My answer when you cleared what your issue is
Code:
public class WordCount
{
public static void main (String[] args)
{
String text ="";
int wordLenght = 0;
text = "Java is awesome for Me";
System.out.println (text);
String [] input = text.split(" ");
List<Integer> list = new ArrayList<>();
for (int i = 0; i < input.length; i++)
{
list.add(input[i].length());
}
Set<Integer> unique = new HashSet<Integer>(list);
for (Integer length : unique) {
System.out.println("There are " + Collections.frequency(list, length) + " words of length " + length);
}
}
}
output:
There are 2 words of length 2
There are 1 words of length 3
There are 1 words of length 4
There are 1 words of length 7
Note: Read about HashSet and Set in Java
Source: http://javarevisited.blogspot.com/2012/06/hashset-in-java-10-examples-programs.html
Let's walk through this:
public class WordCount {
public static void main (String args []) {
String text;
text = "Java";
text is equal to "Java".
System.out.println (text);
Prints "Java"
//Work out the length
String [] input = text.split(" ");
This splits the string "Java" on spaces, of which there are none. So input (which I'd recommend be renamed to something more indicative, like inputs) is equal to an array of one element, and that one element is equal to "Java".
int MaxWordLength = 0;
int WordLength = 0;
for (int i = 0; i < input.length; i++)
{
MaxWordLength = input[i].length();
For each element, of which there is only one, MaxWordLength is set to the length of the first (and only) element, which is "Java"...whose length is 4.
WordLength = MaxWordLength;
So WordLength is now equal to 4.
} //End of working out length
//Work out no. of words
int[] intWordCount = new int[WordLength + 1];
This creates an int array of [WordLength + 1] elements (which is equal to [4 + 1], or 5), where each is initialized to zero.
for(int i = 0; i < input.length; i++) {
intWordCount[input[i].length()]++; }
For each element in input, of which there is only one, this sets the input[i].length()-th element--the fifth, since input[i] is "Java" and it's length is four--to itself, plus one (because of the ++).
Therefore, after this for loop, the array is now equal to [0, 0, 0, 0, 1].
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
So this naturally prints the undesired output.
}
}
}
Your output is different when the input is only "J", because the intWordCount array is shortened to input[i].length() elements, which is now 1. But the value of the last element is still set to "itself plus one", and "itself" is initialized to zero (as all int-array elements are), and then incremented by one (with ++).
for (int i = 1; i < intWordCount.length; i++) {
System.out.println("There are " + intWordCount[i] + " words of length " + MaxWordLength);
}
1) You print out words with intWordCount[i] == 0, which is why you have the "There are 0 words of length X"
2) System.out.println("There are " ... + MaxWordLength); should probably be System.out.println("There are " ... + i);, so you have "There are 0 words of length 1" , "There are 0 words of length 2", etc
I know this question has been solved long time ago, but here is another solution using new features of Java 8. Using Java streams the whole exercise can be written in one line:
Arrays.asList(new String[]{"Java my love"}) //start with a list containing 1 string item
.stream() //start the stream
.flatMap(x -> Stream.of(x.split(" "))) //split the string into words
.map((String x) -> x.length()) //compute the length of each word
.sorted((Integer x, Integer y) -> x-y) //sort words length (not necessary)
.collect(Collectors.groupingBy(x -> x, Collectors.counting())) //this is tricky: collect results to a map: word length -> count
.forEach((x,y) -> {System.out.println("There are " + y + " word(s) with " + x + " letter(s)");}); //now print each result
Probably in few year time this would be a preferred method for solving such problems. Anyway it is worth knowing that such alternative exists.
To count words in text with we used Pattern class with while loop:
I. Case Sensitive word counts
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CountWordsInText {
public static void main(String[] args) {
String paragraph = "I am at office right now."
+ "I love to work at office."
+ "My Office located at center of kathmandu valley";
String searchWord = "office";
Pattern pattern = Pattern.compile(searchWord);
Matcher matcher = pattern.matcher(paragraph);
int count = 0;
while (matcher.find()) {
count++;
}
System.out.println(count);
}
}
II. Case Insensitive word counts
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CountWordsInTextCaseInsensitive {
public static void main(String[] args) {
String paragraph = "I am at office right now."
+ "I love to work at oFFicE."
+"My OFFICE located at center of kathmandu valley";
String searchWord = "office";
Pattern pattern = Pattern.compile(searchWord, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(paragraph);
int count = 0;
while (matcher.find())
count++;
System.out.println(count);
}
}
Idk, but using the length method as much as you have to figure out how the length mechanism works is like defining a word using the word. It's an honorable conquest figuring out how the length method works, but you should probably avoid using the length method.
I have a trouble with the for loop method that only loop 1 times whats is the problem? In the array was no problem at all, it able to print the value I want to.
here is my code:
public static void main(String[] args){
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
String[] word = s.split(",");
StringBuffer str = new StringBuffer();
Integer total = 0;
for (int y = 0; y < word.length; y++){
if(word[y].toString().equals("Apple2") ){
total++;
//str.append(word[y].toString());
}else if(word[y].toString().equals("Apple3") ){
total++;
//str.append(word[y].toString());
}else if(word[y].toString().equals("Apple4") ){
total++;
//str.append(word[y].toString());
}
else if(word[y].toString().equals("Apple1") ){
total++;
//str.append(word[y].toString());
}
}
System.out.println( word[0] + word[1] + word[2] + word[3] + word[4] + word.length);
System.out.println(str + "hihi" + total);
}
The others have nailed the cause of your problem. However, the fix they suggest is rather too specific ... and fragile. (Splitting with split("\\s*,\\s*") is better but it won't cope with whitespace at the start / end of the entire string.)
I suggest that you continue to use split(","), but trim the words before testing; e.g.
for (int y = 0; y < word.length; y++) {
String trimmed = word[y].trim();
if (trimmed.equals("Apple2")) {
total++;
//str.append(trimmed.toString());
} else if (trimmed.equals("Apple3")) {
// etcetera
or better still:
String[] words = s.split(",");
for (String word : words) {
String trimmed = word.trim();
if (trimmed.equals("Apple2")) {
total++;
//str.append(trimmed.toString());
} else if (trimmed.equals("Apple3")) {
// etcetera
That will make your code work irrespective of the whitespace characters around the commas and at the start and end of the string. Robustness is good, especially if it costs next to nothing to implement.
Finally, you could even replace the if / else if / ... stuff with a Java 7 String switch statement.
Try splitting on ", " (with space)
String[] word = s.split(", ");
without that space in split word[1] would look like " Apple1" instead "Apple1"
Other option would be calling word[y].trim().equals("Apple2") to get rid of that additional space, but I would say including it in split is better. If you aren't sure how many white-spaces can be near comma you can split this way split("\\s*,\\s*") to include all white-spaces around comma.
Also as Matt Ball pointed in his comment you don't need to call toString() on word[y] since it is already String.
you ignore the space during split. String[] word = s.split(", ");
You'are split by "," but your String contains ", ".
You can change the s.split(","); to s.split(", ");
Or trim the split's result like this :
public static void main(String[] args) {
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
String[] word = s.split(",");
StringBuffer str = new StringBuffer();
Integer total = 0;
for (int y = 0; y < word.length; y++) {
if (word[y].trim().equals("Apple2")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple3")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple4")) {
total++;
// str.append(word[y].toString());
} else if (word[y].trim().equals("Apple1")) {
total++;
// str.append(word[y].toString());
}
}
System.out.println(word[0] + word[1] + word[2] + word[3] + word[4]
+ word.length);
System.out.println(str + "hihi" + total);
}
There is nothing wrong with your code but the problem lies in the String that you are giving to the variable.
String s = "Apple0, Apple1, Apple2, Apple3, Apple4";
Here the string contains spaces between them after the comma. So that when you split your string it splits like
word[0]= "Apple0"
word[1]= " Apple1"
word[2]= " Apple2"
word[3]= " Apple3"
and so on.
So that when you compare like
word[y].equals("Apple1") it returns false because " Apple1" and "Apple1" are two different strings. So that initialize your string like this
String s = "Apple0,Apple1,Apple2,Apple3,Apple4"; // without white spaces
It will work fine. Or you can use trim method in your existing code without changing String like
word[y].trim().equals("Apple1") //It will trim all the leading and trailing white spaces.
Hope this helps.
I have to find the last word in a string and can't understand why my code isn't working. This is what I have:
int i, length;
String j, lastWord;
String word = "We the people of the United States in order to form a more perfect union";
length = word.length();
for (i = length - 1; i > 0; i--)
{
j = word.substring(i, i + 1);
if (j.equals(" ") == true);
{
lastWord = word.substring(i);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
}
However, when I run it, it prints the last letter. I know I could use
String lastWord = word.substring(word.lastIndexOf(" ") + 1)
But I'm pretty sure my teacher doesn't want me to do it this way. Any help?
You need to remove the ; after the if to make it work:
if (j.equals(" ")) // <== No semicolon, and no == true
{
lastWord = word.substring(i);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
You do not need == true for booleans inside control statements, either.
Finally, making single-character substrings is more expensive than using single characters. Consider using charAt(i) instead:
if (word.charAt(i) == ' ') // Single quotes mean one character
{
lastWord = word.substring(i+1);
System.out.println("Last word: " + lastWord);
break; // there is a better way to stop the loop
}
You've terminated the if statement. It should be,
if(j.equals(" "))
{
...
}
Just take that ; from if (j.equals(" ") == true); out.
Your code remade cleaner:
String word = "We the people of the United States in order to form a more perfect union";
for (int i = word.length() - 1; i > 0; i--)
if (word.charAt(i - 1) == ' ') {
System.out.println("Last word: " + word.substring(i));
break; // To stop the loop
}
Minimum iterations.
Convert the string to char array and look for space from the end of array. Don't forget to remove white spaces from the end using trim() as they could be counted as separate words.
s = s.trim();
char[] c = s.toCharArray();
for(int i=0; i<c.length; i++)
{
if(c[c.length-1-i]==' ')
{
return s.substring(c.length-1-i);
}
}
return s;
This also covers the null string case.
Another alternative using split.
s = s.trim();
String[] strs = new s.split(' ');
return str[str.length-1];
The semicolon after your "if" statement means "do nothing." Also, the "== true" is redundant. Lastly, you don't want to include the space you just found. Try this:
for (i = length - 1; i > 0; i--)
{
j = word.substring(i, i + 1);
if (j.equals(" "))
{
lastWord = word.substring(i + 1);
System.out.println("Last word: " + lastWord);
i = -1; //to stop the loop
}
}
There's a method for strings to split up at http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#split%28java.lang.String%29
Splits this string around matches of the given regular expression.
This method works as if by invoking the two-argument split method with the given expression and a limit argument of zero. Trailing empty strings are therefore not included in the resulting array.
A good, fast and easier way would be:
word = word.split(" ")[word.length-1];
split() returns an array of substrings based on " ". Since an array starts with 0, its last element is the length of the array - 1.