How to flip two words in a sentence in java like
Input: "hi how are you doing today jane"
Output: "how hi you are today doing jane"
what I tried:
String s = "hi how are you doing today jane";
ArrayList<String> al = new ArrayList<>();
String[] splitted = s.split("\\s+");
int n = splitted.length;
for(int i=0; i<n; i++) {
al.add(splitted[i]);
}
for(int i=0; i<n-1; i=i+2) {
System.out.print(al.get(i+1)+" "+al.get(i)+" ");
}
if((n%2) != 0) {
System.out.print(al.get(n - 1));
}
output I'm getting:
"how hiyou aretoday doing"
As you asked to do with only one loop and without extensive use of regex, here is another solution using Collections.swap:
String s = "hi how are you doing today jane";
List<String> splitted = new ArrayList<>(List.of(s.split("\\s+")));
for(int i = 0; i < splitted.size() - 1; i += 2)
Collections.swap(splitted, i, i + 1);
s = String.join(" ", splitted);
System.out.println(s);
Output:
how hi you are today doing jane
Since you're using split() which takes a regex, it would seem that using regex is a valid solution, so use it:
replaceAll("(\\w+)(\\W+)(\\w+)", "$3$2$1")
Explanation
(\\w+) Match first word, and capture it as group 1
(\\W+) Match the characters between the 2 words, and capture them as group 2
(\\w+) Match second word, and capture it as group 3
$3$2$1 Replace the above with the 3 groups in reverse order
Example
System.out.println("hi how are you doing today jane".replaceAll("(\\w+)(\\W+)(\\w+)", "$3$2$1"));
Output
how hi you are today doing jane
Note: Since your code used split("\\s+"), your definition of a "word" is a sequence of non-whitespace characters. To use that definition of a word, change the regex to:
replaceAll("(\\S+)(\\s+)(\\S+)", "$3$2$1")
If you want old-school fori loop and bufor/temp value solution, here you are:
public static void main(String[] args) {
String s = "hi how are you doing today jane";
String flip = flip(s);
System.out.println(flip);
}
private static String flip(String sentence) {
List<String> words = Arrays.asList(sentence.split("\\s+"));
for (int i = 0; i < words.size(); i += 2) {
if (i + 1 < words.size()) {
String tmp = words.get(i + 1);
words.set(i + 1, words.get(i));
words.set(i, tmp);
}
}
return words.stream().map(String::toString).collect(Collectors.joining(" "));
}
However Pauls solultion is way better since it is java, and we are no more in the stone age era :)
Related
I have a string for example,
String s = "This is a String which needs to be split after every n words";
Suppose I have to divide this string after every 5 words of which the output should be,
Arraylist stringArr = ["This is a String which", "needs to be split after", "every n words"]
How can do this and store it in an array in java
While there isn't a built-in way for Java to do this, it's fairly easy to do using Java's standard regular-expressions.
My example below tries to be clear, rather than trying to be the "best" way.
It's based on finding groups of five "words" followed by a space, based on the regular expression ([a-zA-Z]+ ){5}) which says
• [a-zA-Z]+ find any letters, repeated (+)
• followed by a space
• (...) gather into groups
• {5} exactly 5 times
You may want things besides letters, and you may want to allow multiple spaces or any whitespace, not just spaces, so later in the example I change the regex to (\\S+\\s+){5} where \S means any non-whitespace and \s means any whitespace.
This first goes through the process in the main method, displaying output along the way that, I hope, makes it clear what's going on; then shows how the process could be made into a method.
I create a method that will split a line into groups of n words, then call it to split your string every 5 words then again but every 3 words.
Here it is:
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LineSplitterExample
{
public static void main(String[] args)
{
String s = "This is a String which needs to be split after every n words";
//Pattern p = Pattern.compile("([a-zA-Z]+ +){5}");
Pattern p = Pattern.compile("(\\S+ +){5}");
Matcher m = p.matcher(s);
int last = 0;
List<String> collected = new ArrayList<>();
while (m.find()) {
System.out.println("Group Count = " + m.groupCount());
for (int i=0; i<m.groupCount(); i++) {
final String found = m.group(i);
System.out.printf("Group %d: %s%n", i, found);
collected.add(found);
// keep track of where the last group ended
last = m.end();
System.out.println("'m.end()' is " + last);
}
}
// collect the final part of the string after the last group
String tail = s.substring(last);
System.out.println(tail);
collected.add(tail);
String[] result = collected.toArray(new String[0]);
System.out.println("result:");
for (int n=0; n<result.length; n++) {
System.out.printf("%2d: %s%n", n, result[n]);
}
// Put a little space after the output
System.out.println("\n");
// Now use the methods...
String[] byFive = splitByWords(s, 5);
displayArray(byFive);
String[] byThree = splitByWords(s, 3);
displayArray(byThree);
}
private static String[] splitByWords(final String s, final int n)
{
//final Pattern p = Pattern.compile("([a-zA-Z]+ +){"+n+"}");
final Pattern p = Pattern.compile("(\\S+\\s+){"+n+"}");
final Matcher m = p.matcher(s);
List<String> collected = new ArrayList<>();
int last = 0;
while (m.find()) {
for (int i=0; i<m.groupCount(); i++) {
collected.add(m.group(i));
last = m.end();
}
}
collected.add(s.substring(last));
return collected.toArray(new String[0]);
}
private static void displayArray(final String[] array)
{
System.out.println("Array:");
for (int i=0; i<array.length; i++) {
System.out.printf("%2d: %s%n", i, array[i]);
}
}
}
The output I got by running this is:
Group Count = 1
Group 0: This is a String which
'm.end()' is 23
Group Count = 1
Group 0: needs to be split after
'm.end()' is 47
every n words
result:
0: This is a String which
1: needs to be split after
2: every n words
Array:
0: This is a String which
1: needs to be split after
2: every n words
Array:
0: This is a
1: String which needs
2: to be split
3: after every n
4: words
You can do it with a combination of replaceAll and split
S{N} - matches N iterations of S
() - regular expression capture group
$1 - back reference to the captured group
Replace every occurrence of N words with that occurrence followed by a special delimiter (in this case ###). Then split on that delimiter.
public static String[] splitNWords(String s, int count) {
String delim = "((?:\\w+\\s+){"+count+"})";
return s.replaceAll(delim, "$1###").split("###");
}
Demo
String s = "This is a String which needs to be split after every n words";
for (int i = 1; i < 5; i++) {
String[] arr = splitNWords(s, i);
System.out.println("Splitting on " + i + " words.");
for (String st : arr) {
System.out.println(st);
}
System.out.println();
}
prints
Splitting on 1 words.
This
is
a
String
which
needs
to
be
split
after
every
n
words
Splitting on 2 words.
This is
a String
which needs
to be
split after
every n
words
Splitting on 3 words.
This is a
String which needs
to be split
after every n
words
Splitting on 4 words.
This is a String
which needs to be
split after every n
words
I dont think there is a split every n words. You need to specify a pattern, like blank space. You can for instance, Split every blank and later iterate over the array created and make another one with tue number of words you want.
Regards
This question already has answers here:
How to split a string, but also keep the delimiters?
(24 answers)
Closed 7 years ago.
How do you split a string of words and retain whitespaces?
Here is the code:
String words[] = s.split(" ");
String s contains: hello world
After the code runs, words[] contains: "hello" "" world
Ideally, it should not be an empty string in the middle, but contain both whitespaces: words[] should be: "hello" " " " " world
How do I get it to have this result?
You could use lookahead/lookbehind assertions:
String[] words = "hello world".split("((?<=\\s+)|(?=\\s+))");
where (?<=\\s+) and (?=\\s+) are zero-width groups.
If you can tolerate both white spaces together in one string, you can do
String[] words = s.split("\\b");
Then words contains ("hello", " ", "world").
s.split("((?<= )|(?= ))"); is one way.
Technically, the regular expression is using lookahead and lookbehind. The single space after each = is the delimiter.
You could do something like this:
List<String> result = new LinkedList<>();
int rangeStart = 0;
for (int i = 0; i < s.length(); ++i) {
if (Character.isWhitespace(s.charAt(i))) {
if (rangeStart < i) {
result.add(s.substring(rangeStart, i));
}
result.add(Character.toString(s.charAt(i)));
rangeStart = i + 1;
}
}
if (rangeStart < s.length()) {
result.add(s.substring(rangeStart));
}
Yeah, no regexes, sue me. This way you can see how it works more easily.
I want to select the first N words of a text string.
I have tried split() and substring() to no avail.
What I want is to select the first 3 words of the following prayer and copy them to another variable.
For example if I have a string:
String greeting = "Hello this is just an example"
I want to get into the variable Z the first 3 words so that
Z = "Hello this is"
String myString = "Copying first N numbers of words to a string";
String [] arr = myString.split("\\s+");
//Splits words & assign to the arr[] ex : arr[0] -> Copying ,arr[1] -> first
int N=3; // NUMBER OF WORDS THAT YOU NEED
String nWords="";
// concatenating number of words that you required
for(int i=0; i<N ; i++){
nWords = nWords + " " + arr[i] ;
}
System.out.println(nWords);
NOTE : Here .split() function returns an array of strings computed by splitting a given string around matches of the given regular expression
so if i write the code like follows
String myString = "1234M567M98723651";
String[] arr = myString.split("M"); //idea : split the words if 'M' presents
then answers will be : 1234 and 567 where stored into an array.
This is doing by storing the split values into the given array. first split value store to arr[0], second goes to arr[1].
Later part of the code is for concatenating the required number of split words
Hope that you can get an idea from this!!!
Thank you!
public String getFirstNStrings(String str, int n) {
String[] sArr = str.split(" ");
String firstStrs = "";
for(int i = 0; i < n; i++)
firstStrs += sArr[i] + " ";
return firstStrs.trim();
}
Now getFirstNStrings("Hello this is just an example", 3); will output:
Hello this is
You could try something like:
String greeting = "Hello this is just an example";
int end = 0;
for (int i=0; i<3; i++) {
end = greeting.indexOf(' ', end) + 1;
}
String Z = greeting.substring(0, end - 1);
N.B. This assumes there are at least three space characters in your source string. Any less and this code will probably fail.
Add this in a utility class, such as Util.java
public static String getFirstNWords(String s, int n) {
if (s == null) return null;
String [] sArr = s.split("\\s+");
if (n >= sArr.length)
return s;
String firstN = "";
for (int i=0; i<n-1; i++) {
firstN += sArr[i] + " ";
}
firstN += sArr[n-1];
return firstN;
}
Usage:
Util.getFirstNWords("This will give you the first N words", 3);
---->
"This will give"
If you use Apache Commons Lang3, you can make it a little shorter like this:
public String firstNWords(String input, int numOfWords) {
String[] tokens = input.split(" ");
tokens = ArrayUtils.subarray(tokens, 0, numOfWords);
return StringUtils.join(tokens, ' ');
}
Most of the answers posted already use regular expressions which can become an overhead if we have to process a large number of strings. Even str.split(" ") uses regular expression operations internally. dave's answer is perhaps the mos efficient, but it does not handle correctly strings that have multiple spaces occurring together, beside assuming that regular space is the only word separator and that the input string has 3 or more words (an assumption he has already called out). If using Apache Commons in an option, then I would use the following code as it is not only concise and avoids using regular expression even internally but also handled gracefully input strings that have less than 3 words:
/* Splits by whitespace characters. All characters after the 3rd whitespace,
* if present in the input string, go into the 4th "word", which could really
* be a concanetation of multiple words. For the example in the question, the
* 4th "word" in the result array would be "just an example". Invoking the
* utility method with max-splits specified is slightly more efficient as it
* avoids the need to look for and split by space after the first 3 words have
* been extracted
*/
String[] words = StringUtils.split(greeting, null, 4);
String Z = StringUtils.join((String[]) ArrayUtils.subarray(words, 0, 3), ' ');
String original = "This is a sentence.Rajesh want to test the application for the word split.";
List matchList = new ArrayList();
Pattern regex = Pattern.compile(".{1,10}(?:\\s|$)", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(original);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
System.out.println("Match List "+matchList);
I need to parse text into an array of lines that do not exceed 10 characters in length and should not have a break in word at the end of the line.
I used below logic in my scenario but the problem it is parsing to the nearest white space after 10 characters if there is a break at end of line
for eg: The actual sentence is "This is a sentence.Rajesh want to test the application for the word split." But after logic execution its getting as below.
Match List [This is a , nce.Rajesh , want to , test the , pplication , for the , word , split.]
OK, so I've managed to get the following working, with max line length of 10, but also splitting the words that are longer than 10 correctly!
String original = "This is a sentence. Rajesh want to test the applications for the word split handling.";
List matchList = new ArrayList();
Pattern regex = Pattern.compile("(.{1,10}(?:\\s|$))|(.{0,10})", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(original);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
System.out.println("Match List "+matchList);
This is the result:
This is a
sentence.
Rajesh want
to test
the
applicatio
ns word
split
handling.
This question was tagged as Groovy at some point. Assuming a Groovy answer is still valid and you are not worried about preserving multiple white spaces (e.g. ' '):
def splitIntoLines(text, maxLineSize) {
def words = text.split(/\s+/)
def lines = ['']
words.each { word ->
def lastLine = (lines[-1] + ' ' + word).trim()
if (lastLine.size() <= maxLineSize)
// Change last line.
lines[-1] = lastLine
else
// Add word as new line.
lines << word
}
lines
}
// Tests...
def original = "This is a sentence. Rajesh want to test the application for the word split."
assert splitIntoLines(original, 10) == [
"This is a",
"sentence.",
"Rajesh",
"want to",
"test the",
"application",
"for the",
"word",
"split."
]
assert splitIntoLines(original, 20) == [
"This is a sentence.",
"Rajesh want to test",
"the application for",
"the word split."
]
assert splitIntoLines(original, original.size()) == [original]
I avoided regex as is doesn't pull the weight. This code word-wraps, and if a single word is more than 10 chars, breaks it. It also takes care of excess whitespace.
import static java.lang.Character.isWhitespace;
public static void main(String[] args) {
final String original =
"This is a sentence.Rajesh want to test the application for the word split.";
final StringBuilder b = new StringBuilder(original.trim());
final List<String> matchList = new ArrayList<String>();
while (true) {
b.delete(0, indexOfFirstNonWsChar(b));
if (b.length() == 0) break;
final int splitAt = lastIndexOfWsBeforeIndex(b, 10);
matchList.add(b.substring(0, splitAt).trim());
b.delete(0, splitAt);
}
System.out.println("Match List "+matchList);
}
static int lastIndexOfWsBeforeIndex(CharSequence s, int i) {
if (s.length() <= i) return s.length();
for (int j = i; j > 0; j--) if (isWhitespace(s.charAt(j-1))) return j;
return i;
}
static int indexOfFirstNonWsChar(CharSequence s) {
for (int i = 0; i < s.length(); i++) if (!isWhitespace(s.charAt(i))) return i;
return s.length();
}
Prints:
Match List [This is a, sentence.R, ajesh, want to, test the, applicatio, n for the, word, split.]
I need to count the number of spaces in my string but my code gives me a wrong number when i run it, what is wrong?
int count=0;
String arr[]=s.split("\t");
OOPHelper.println("Number of spaces are: "+arr.length);
count++;
s.length() - s.replaceAll(" ", "").length() returns you number of spaces.
There are more ways. For example"
int spaceCount = 0;
for (char c : str.toCharArray()) {
if (c == ' ') {
spaceCount++;
}
}
etc., etc.
In your case you tried to split string using \t - TAB. You will get right result if you use " " instead. Using \s may be confusing since it matches all whitepsaces - regular spaces and TABs.
Here is a different way of looking at it, and it's a simple one-liner:
int spaces = s.replaceAll("[^ ]", "").length();
This works by effectively removing all non-spaces then taking the length of what’s left (the spaces).
You might want to add a null check:
int spaces = s == null ? 0 : s.replaceAll("[^ ]", "").length();
Java 8 update
You can use a stream too:
long spaces = s.chars().filter(c -> c == (int)' ').count();
Fastest way to do this would be:
int count = 0;
for(int i = 0; i < str.length(); i++) {
if(Character.isWhitespace(str.charAt(i))) count++;
}
This would catch all characters that are considered whitespace.
Regex solutions require compiling regex and excecuting it - with a lot of overhead. Getting character array requires allocation. Iterating over byte array would be faster, but only if you are sure that your characters are ASCII.
\t will match tabs, rather than spaces and should also be referred to with a double slash: \\t. You could call s.split( " " ) but that wouldn't count consecutive spaces. By that I mean...
String bar = " ba jfjf jjj j ";
String[] split = bar.split( " " );
System.out.println( split.length ); // Returns 5
So, despite the fact there are seven space characters, there are only five blocks of space. It depends which you're trying to count, I guess.
Commons Lang is your friend for this one.
int count = StringUtils.countMatches( inputString, " " );
If you use Java 8, the following should work:
long count = "0 1 2 3 4.".chars().filter(Character::isWhitespace).count();
This will also work in Java 8 using Eclipse Collections:
int count = Strings.asChars("0 1 2 3 4.").count(Character::isWhitespace);
Note: I am a committer for Eclipse Collections.
Your code will count the number of tabs and not the number of spaces. Also, the number of tabs will be one less than arr.length.
Another way using regular expressions
int length = text.replaceAll("[^ ]", "").length();
The code you provided would print the number of tabs, not the number of spaces. The below function should count the number of whitespace characters in a given string.
int countSpaces(String string) {
int spaces = 0;
for(int i = 0; i < string.length(); i++) {
spaces += (Character.isWhitespace(string.charAt(i))) ? 1 : 0;
}
return spaces;
}
A solution using java.util.regex.Pattern / java.util.regex.Matcher
String test = "foo bar baz ";
Pattern pattern = Pattern.compile(" ");
Matcher matcher = pattern.matcher(test);
int count = 0;
while (matcher.find()) {
count++;
}
System.out.println(count);
please check the following code, it can help
public class CountSpace {
public static void main(String[] args) {
String word = "S N PRASAD RAO";
String data[];int k=0;
data=word.split("");
for(int i=0;i<data.length;i++){
if(data[i].equals(" ")){
k++;
}
}
System.out.println(k);
}
}
The simple and fastest way to count spaces
String fav="foo hello me hi";
for( int i=0; i<fav.length(); i++ ) {
if(fav.charAt(i) == ' ' ) {
counter++;
}
}
I just had to do something similar to this and this is what I used:
String string = stringValue;
String[] stringArray = string.split("\\s+");
int length = stringArray.length;
System.out.println("The number of parts is: " + length);
public static void main(String[] args) {
String str = "Honey dfd tEch Solution";
String[] arr = str.split(" ");
System.out.println(arr.length);
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (!arr[i].trim().isEmpty()) {
System.out.println(arr[i]);
count++;
}
}
System.out.println(count);
}
public static void main(String[] args) {
Scanner input= new Scanner(System.in);`
String data=input.nextLine();
int cnt=0;
System.out.println(data);
for(int i=0;i<data.length()-1;i++)
{if(data.charAt(i)==' ')
{
cnt++;
}
}
System.out.println("Total number of Spaces in a given String are " +cnt);
}
This program will definitely help you.
class SpaceCount
{
public static int spaceCount(String s)
{ int a=0;
char ch[]= new char[s.length()];
for(int i = 0; i < s.length(); i++)
{ ch[i]= s.charAt(i);
if( ch[i]==' ' )
a++;
}
return a;
}
public static void main(String... s)
{
int m = spaceCount("Hello I am a Java Developer");
System.out.println("The number of words in the String are : "+m);
}
}
The most precise and exact plus fastest way to that is :
String Name="Infinity War is a good movie";
int count =0;
for(int i=0;i<Name.length();i++){
if(Character.isWhitespace(Name.charAt(i))){
count+=1;
}
}
System.out.println(count);
import java.util.Scanner;
import java.io.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in).useDelimiter("\n");
String str = sc.next();
int spaceCount=0;
str = str.toLowerCase();
for(int i = 0; i < str.length(); i++) {
if(str.charAt(i)==' '){
spaceCount++;
}
}
System.out.println("Number of spaces: "+ spaceCount);
}
}