I'm trying to make a function reverse a string of integers, but am only able to mirror it completely, with the following piece of code I found. (I want to translate it from string to string without arrays or lists, preferably recursively)
static String reverseMe(String s) {
if(s.length() == 0)
return "";
return s.charAt(s.length() - 1) + reverseMe(s.substring(0,s.length()-1));
}
So for example (1 2 41) returns (14 2 1) when I really want (41 2 1). I would like some way for Java to start reversing when it encounters a space (or any none-integer) and keep the integers themselves as they are.
A modified version of your function using String#lastIndexOf:
String reverseMe(String s)
{
if (s.length() == 0)
return "";
int index = s.lastIndexOf(" ");
if (index == -1) // not found, thus just return the string
return s;
else // found, thus concat last part with recursive call
return s.substring(index + 1) + " " + reverseMe(s.substring(0, index));
}
Or you can use String#split to separate by spaces and just loop through in reverse and concatenate.
String reverse(String s)
{
String reversed = "";
String[] split = s.split(" ");
reversed = split[split.length-1];
for (int i = split.length-2; i >= 0; i--)
{
reversed += " " + split[i];
}
return reversed;
}
Although StringBuilder would make for a more efficient option, since it doesn't require all that string copying.
You can also use StringTokenized
StringTokenizer st = new StringTokenizer("1 2 41");
StringBuilder sb = new StringBuilder();
while (st.hasMoreTokens()) {
if (sb.length() > 0) {
sb.insert(0, ' ');
}
sb.insert(0, st.nextToken());
}
System.out.println(sb.toString());
One another solution among these
static String reverseMe(String s) {
if(s.length() == 0)
return "";
String sa[] = s.split(" ");
List<String> newlist = Arrays.asList(sa);
Collections.reverse(newlist);
return newlist.toString();
}
Non recursive, guava present.
String input = "123 456 789 tt 012";
Iterable<String> tokens = Splitter.on(Pattern.compile("[^\\d]")).omitEmptyStrings().split(input);
for(String token: tokens){
StringBuilder builder = new StringBuilder(token);
System.out.println(builder.reverse().toString());
}
Or without guava:
String input = "123 456 789 tt 012";
String tokens [] = input.split("[^\\d]+");
for(String token:tokens){
StringBuilder builder = new StringBuilder(token);
System.out.println(builder.reverse().toString());
}
If you want to do it recursively,this would do it!
public static String reverseIt(final String inp,final int lastIndex,String out)
{
int i=lastIndex;
while(inp.charAt(i)!=' ' && i!=-1){i--;if(i==-1)break;}
out+=(inp.substring(i+1,lastIndex+1));if(i!=-1)out+=" ";
if(lastIndex!=0)return reverseIt(inp,i-1,out);
else return out;
}
You can now call it as
reverseIt(input,input.length-1,output);
If you are not particular with recursion, the below solution would work.
static String reversMe(String str) {
StringBuffer strBuf = new StringBuffer();
String strArray = str.split(" ");
for(int i = strArray.length();i>=0; i--) {
strBuf.append(strArray[i]).append(" ");
}
return strBuf.toString().trim();
}
It can be as simple as this.
String num="1 2 41";
StringTokenizer sTok=new StringTokenizer(num, " ");
String revnum="";
while(sTok.hasMoreTokens())
{
revnum=sTok.nextToken()+" "+revnum;
}
System.out.println(revnum);
Yet another recursive variant using Tail call recursion.
public static String reverseMe(String s) {
StringBuilder sb = new StringBuilder();
return reverseMe(s.split(" "), sb);
}
public static String reverseMe(String[] s, StringBuilder sb) {
if (s.length == 0) {
return sb.toString().trim();
} else {
return reverseMe(Arrays.copyOfRange(s, 1, s.length), sb.insert(0, " ").insert(0, s[0]));
}
}
Related
can anyone please tell me how to write test case in the below code
public static String reverseWord(String str) {
String a[] = str.split(" ");
try {
for (int i = a.length - 1; i >= 0; i--) {
System.out.print(a[i] + " ");
}
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
I have written the below test case but it is failed
#Test
public void testReverseWord() {
assertEquals("world hello", Logic.reverseWord("hello world"));
}
You return exactly the same String as you get as argument, changes that you are doing are printed to the console instead of being returned.
Try this code instead. I am creating StringBuilder (you can read more about it here https://docs.oracle.com/javase/tutorial/java/data/buffers.html) which is used for String concatenation. Note that I am adding space only if it is not the last word - so that your returned String doesn't have space at the end. At the end by calling toString() on StringBuilder object I am returning new reversed String, exactly what you wanted.
public static String reverseWord(String str) {
String a[] = str.split(" ");
StringBuilder builder = new StringBuilder();
try {
for (int i = a.length - 1; i >= 0; i--) {
builder.append(a[i]);
if (i != 0) {
builder.append(" ");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return builder.toString();
}
Your test case is correct, but the method itself is wrong, you are splitting the string then just printing out values instead of creating a new string and concatenating those values there, so instead of System.out.print(a[i] + " "); introduce a new String outside the loop String result = "" and concatenate the values:
String a[] = str.split(" ");
String result = "";
for (int i = a.length - 1; i >= 0; i--) {
result += a[i];
if (i != 0)
result += " ";
}
return result;
A more optimized way is using a StringBuilder since a String is immutable every time you append to it, a new instance is created - also no need for a try-catch block
Your function return the same input, so you need to modify it, you can easily use StringBuilder class
public static String reverseWord(String str) {
String[] words = str.split(" ");
StringBuilder builder = new StringBuilder(str.length());
for (int i = words.length - 1; i >= 0; i--) {
builder.append(words[i]).append(" ");
}
return builder.toString().trim();
}
I want to reverse a whole String. For example, "Cat is running" should give output "running is cat".
I have tried a lot but I am unable to do it. It shows "gninnur si taC". Kindly help me that it should take "cat" as a single character instead of taking 'c' as a single character.
Here is the code:
public static void main(String[] args) {
String str = "Cat is running";
System.out.println("Before recursion: " + str);
System.out.println("After recursion: " + reverse(str));
}
public static String reverse(String str) {
if(str.isEmpty())
return str;
String s = "";
for(int i = 0; i < str.length(); i++) {
s = s + str.charAt(i);
}
return reverse(s.substring(1)) + s.charAt(0);
}
You have to find the first word in the String, pass the rest of the String to the recursive call, and append the first word at the end:
public static String reverse(String str) {
if(str.isEmpty() || !str.contains(" "))
return str;
int sep = str.indexOf(' ');
return reverse(str.substring(sep+1)) + " " + str.substring(0,sep);
}
Output:
Before recursion: Cat is running
After recursion: running is Cat
BTW, the loop is your original code is pointless. You can simply use str directly instead of creating a copy of it.
You can make it even shorter with:
public static String reverse(String str) {
int sep = str.indexOf(' ');
return sep >= 0 ? reverse(str.substring(sep+1)) + " " + str.substring(0,sep) : str;
}
I think I made it a little less good than #Eran but I already wrote:
private static String reverse(String str) {
if (str.isEmpty() || !str.contains(" "))
return str;
StringBuilder sb = new StringBuilder(" ");
int i = 0;
while (i < str.length() && str.charAt(i) != ' ') {
sb.append(str.charAt(i));
i++;
}
return reverse(str.substring(i + 1)) + sb.toString();
}
I have written following code to get next word from a string in Java. I feel its very raw and I shouldn't have to write so much code for this but couldn't find any other way. Want to know if there are better ways available to do same:
public static String getNextWord(String str, String word) {
String nextWord = null;
// to remove multi spaces with single space
str = str.trim().replaceAll(" +", " ");
int totalLength = str.length();
int wordStartIndex = str.indexOf(word);
if (wordStartIndex != -1) {
int startPos = wordStartIndex + word.length() + 1;
if (startPos < totalLength) {
int nextSpaceIndex = str.substring(startPos).indexOf(" ");
int endPos = 0;
if (nextSpaceIndex == -1) {
// we've reached end of string, no more space left
endPos = totalLength;
} else {
endPos = startPos + nextSpaceIndex;
}
nextWord = str.substring(startPos, endPos);
}
}
return nextWord;
}
Note: the input word could be anything (multi words, single word, a word not in string etc).
Test:
String text = "I am very happy with life";
System.out.println(StringUtil.getNextWord(text, "I"));
System.out.println(StringUtil.getNextWord(text, "I am"));
System.out.println(StringUtil.getNextWord(text, "life"));
System.out.println(StringUtil.getNextWord(text, "with"));
System.out.println(StringUtil.getNextWord(text, "fdasfasf"));
System.out.println(StringUtil.getNextWord(text, text));
Output:
am
very
null
life
null
null
This sounds like a job for regex. Something like this:
public static String getNextWord(String str, String word){
Pattern p = Pattern.compile(word+"\\W+(\\w+)");
Matcher m = p.matcher(str);
return m.find()? m.group(1):null;
}
Hope this will serve your purpose.
public static String getNextWord(String str, String word) {
String[] words = str.split(" "), data = word.split(" ");
int index = Arrays.asList(words).indexOf((data.length > 1) ? data[data.length - 1] : data[0]);
return (index == -1) ? "Not Found" : ((index + 1) == words.length) ? "End" : words[index + 1];
}
Input (single word) :
String str = "Auto generated method stub";
String word = "method";
Out Put:
next word: stub
Input (multi-words) :
String str = "Auto generated method stub";
String word = "Auto generated";
Out Put:
next word: method
Input (missing word) :
String str = "Auto generated method stub";
String word = "was";
Out Put:
next word: Not Found
Input (end word) :
String str = "Auto generated method stub";
String word = "stub";
Out Put:
next word: End
You can create an array of words by doing this:
String[] words = str.split(" ");
This splits the string into strings when separated by a space. Note you keep needing to trim the str as you want to.
Now, you can somehow search in the array by finding some word and adding 1 to the index to get the next one.
nextword = words[words.indexOf(word) + 1];
I think, this solution works correctly:
public static String getNextWord(String str, String word) {
String[] strArr = str.split(word);
if(strArr.length > 1) {
strArr = strArr[1].trim().split(" ");
return strArr[0];
}
return null;
}
You can try the below code.
public static String getNextWord(String str, String word) {
try {
List<String> text = Arrays.asList(str.split(" "));
List<String> list = Arrays.asList(word.split(" "));
int index_of = text.indexOf(list.get(list.size() - 1));
return (index_of == -1) ? null : text.get(index_of + 1);
} catch(Exception e) {
return null;
}
}
Hope this is what you are looking for:
public static void main(String[] args) {
String text = "I am very happy with life";
System.out.println(getNextWord(text,"am"));
System.out.println(getNextWord(text,"with"));
System.out.println(getNextWord(text,"happy"));
System.out.println(getNextWord(text,"I"));
System.out.println(getNextWord(text,"life"));
}
public static String getNextWord(String text,String finditsNext){
String result = "There is no next string";
try {
int findIndex = text.indexOf(finditsNext);
String tep = text.substring(findIndex);
if(tep.indexOf(" ") >0) {
tep = tep.substring(tep.indexOf(" ") + 1);
if(tep.indexOf(" ") >0)
result = tep.substring(0, tep.indexOf(" "));
else
result = tep;
}
}catch (IndexOutOfBoundsException ex){
}
return result;
}
The output for the above is:
very
life
with
am
There is no next string
I need to reverse 5 or more character long words in a given string. For example:
* Given string: My name is Michael.
* Output: My name is leahciM.
Rest of the sentence stays the same, just those long words get reversed.
So far I came up with this:
public static String spinWords(String sentence) {
String[] splitWords = sentence.split(" ");
String reversedSentence = "";
String reversedWord = "";
for (String str : splitWords) {
if (str.length() >= 5) {
for (int i = str.length() - 1; i >= 0; i--)
reversedWord += (str.charAt(i) + " ");
}
}
}
And I have reversed those words, but
1) they are in one string, without a space
2) I dont know how to put them back into their places in string
Here is a suggestion:
write a method that reverses a string:
private static String reverse(String s) { ... }
then in your main method, call it when necessary:
if (str.length() >= 5) str = reverse(str);
you then need to put the words back together, presumably into the reversedSentence string:
reversedSentence += str + " "; //you will have an extra space at the end
Side notes:
using a StringBuilder may prove more efficient than string concatenation for longer sentences.
you could put all the words back into a List<String> within the loop and call reversedSentence = String.join(" ", list) after the loop
reversing a string can be done in one line - you should find numerous related Q&As on stackoverflow.
You can use StringBuilder
public static String spinWords(String sentence) {
String[] splitWords = sentence.split(" ");
StringBuilder builder = new StringBuilder();
for (String str : splitWords) {
if (str.length() < 5) {
builder.append(str);
else
builder.append(new StringBuilder(str).reverse().toString());
builder.append(" ");
}
return builder.toString().trim();
}
No need to use anything else you almost had it, just check your "for" loops and remember to add the unreversed string.
public static String spinWords(String sentence) {
String[] splitWords = sentence.split(" ");
String reversedSentence = "";
String reversedWord;
for (String str : splitWords) {
if (str.length() >= 5) {
reversedWord = "";
for (int i = str.length() - 1; i >= 0; i--) {
reversedWord += (str.charAt(i));
}
reversedSentence += " " + reversedWord;
} else {
reversedSentence += " " + str;
}
}
return reversedSentence;
}
Use StringBuilder to build the answer as you process the elements in splitWords.
You may also find the idiom of space with special first-time value (being "") useful.
There was also a bug in your original code.
So here is what I would do:
public class ReverseLongWord {
public static void main(String[] args) {
String testInput = "My name is Michael";
System.out.println(spinWords(testInput));
}
public static String spinWords(String sentence) {
String[] splitWords = sentence.split(" ");
String reversedSentence = "";
StringBuilder sb = new StringBuilder();
String space = ""; // first time special
String reversedWord = "";
for (String str : splitWords) {
if (str.length() >= 5) {
for (int i = str.length() - 1; i >= 0; i--) {
reversedWord += (str.charAt(i)); // Bug fixed
}
sb.append(space + reversedWord);
} else {
sb.append(space + str);
}
space = " "; // second time and onwards
}
return sb.toString();
}
}
The output of this program is the following, as you have specified:
My name is leahciM
I think the reverse method as some people suggest would be the easiest way, here I share my implementation
public static void main(String[] args) {
System.out.println(concatenatePhrase("My name is Michael"));
System.out.println(concatenatePhrase("Some randoms words with differents sizes and random words"));
}
private static String concatenatePhrase(String phrase) {
StringBuilder completePhrase = new StringBuilder();
String[] phrases = phrase.split(" ");
for (String word : phrases) {
if (word.length() >= 5) {
completePhrase.append(reverseWord(word).append(" "));
} else {
completePhrase.append(word).append(" ");
}
}
return completePhrase.toString().trim();
}
private static StringBuilder reverseWord(String wordPassed) {
StringBuilder word = new StringBuilder(wordPassed);
return word.reverse();
}
I'm trying to do a simple reverse task like: change the string "how are you" to "you are how".
this is my code:
public class Program {
public static String revSentence (String str) {
String [] givenString = str.split(" ");
String [] retString = new String[givenString.length];
int last = givenString.length - 1;
for (int i = 0; i < givenString.length; i++) {
retString [i] = givenString[last--];
}
return retString.toString();
}
public static void main(String[] args) {
String m = "how are you";
System.out.println(revSentence(m));
}
}
I'm getting a weird output:
[Ljava.lang.String;#e76cbf7
The output isn't "weird" at all - it's the Object's internal string representation, created by Object.toString(). String[] doesnt override that. If you want to output all entires, loop through them and concatenate them, Best using a StringBuilder to avoid creating unnecessary String instances.
public static String arrayToString (String[] array) {
StringBuilder result = new StringBuilder();
for (String value : array) {
result.append(value);
}
return StringBuilder.toString();
}
If you don'T need that method on it'S own and want to include it in the overall process of reversing the sentence, this is how it may look. It iterates only once, iterating backwards (= counting down) to reverse the sentence.
public static String revSentence (String str) {
String [] givenString = str.split(" ");
StringBuilder result = new StringBuilder();
// no need for 'last', we can use i to count down as well...
for (int i = givenString.length - 1 ; i >= 0; i--) {
result.append(givenString[i]);
}
return result.toString();
}
[Edit]: because of the OPs comment to one of the other answers, about not having learned how to use StringBUilder yet, here is a arrayToStirng method without using one. Note however that this should not be done normally, as it creates useless instances of String whiche are not cleaned up by the GC because of the immutable nature of String(all instances are kept for reuse).
public static String arrayToString (String[] array) {
String result = "";
for (String value : array) {
result += value;
}
return result;
}
Or, without a dedicate arrayToString method:
public static String revSentence (String str) {
String [] givenString = str.split(" ");
String result = "";
for (int i = givenString.length-1 ; i >= 0 ; i--) {
result += givenString[i];
}
return result;
}
Here is a solution:
public class Program {
public static String revSentence (String str) {
String retString = "";
String [] givenString = str.split(" ");
for (int i=givenString.length-1; i>=0; i--) {
retString += givenString[i] + " ";
}
return retString;
}
public static void main(String[] args) {
String m = "how are you";
System.out.print(revSentence(m));
}
}
Modified it to make the "revSentence" function return a String, plus improved the code a bit. Enjoy!
Calling toString() on an array object (in your case retString) doesn't print all array entries, instead it prints object address.
You should print array entries by iterating over them.
Use this code for reversed string
StringBuilder builder = new StringBuilder();
for(String s : retString) {
builder.append(s);
}
return builder.toString();
Calling toString on an array gives you the memory ref which isn't very useful. Try this:
public static String revSentence (String str) {
String[] givenString = str.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = givenString.length - 1; i >= 0; i--) {
sb.append(givenString[i]);
if (i != 0)
sb.append(" ");
}
return sb.toString();
}
the for loop start from greater length to lower and builder.append(givenString[i] + " "); this will concatenate String and return whole sentence you are how you could use both mySentence += givenString[i] + " "; or builder.append(givenString[i] + " "); but the best way is to use StringBuilder class (see docs)
public class Program {
public static String revSentence(String str) {
String[] givenString = str.split(" ");
String[] retString = new String[givenString.length];
int last = givenString.length - 1;
//String mySentence = "";
StringBuilder builder = new StringBuilder();
for (int i = givenString.length - 1; i >= 0; i--) {
// retString [i] = givenString[i];
// mySentence += givenString[i] + " ";
builder.append(givenString[i] + " ");
}
return builder.toString(); // retuning String
//return mySentence;
}
public static void main(String[] args) {
String m = "how are you";
System.out.println(revSentence(m));
}
}
Faster, and shorter:
To reverse a word, use:
public String reverseWord(String s) {
StringBuilder y = new StringBuilder(s);
return y.reverse();
}
Now split and use this method and use Stringbuidler.append to concatenate the all.
And dont forget the space inbetween.