Recursion for printing out words in sentence backwards - java

I'm working on getting a method that prints the words of a sentence out backwards. I'm very close to a solution but am hitting a minor snag.
Here is my code:
public static String reverseString(String str) {
if (str.equals(""))
return "";
else {
int i = str.length() - 1;
while (!Character.isWhitespace(str.charAt(i))) {
if (i - 1 < 0)
break;
i--;
}
return str.substring(i,str.length()) + reverseString(str.substring(0,i));
}
}
Now the problem is the that the output from my test:
String test = "This is a test.";
System.out.println(reverseString(test));
Is giving me this back:
test. a isThis
Now, when I try to bump up the index of the substring being returned and add in the spaces manually, it cuts off the "T" in "This". That is, if I decide to instead return as follows:
return str.substring(i+1,str.length()) + " " + reverseString(str.substring(0,i));
then I get back
test. a is his
Does anyone have any advice or pointers on my implementation in general?

You can change the return statement to this:
return str.substring(i, str.length()).trim() + " " + reverseString(str.substring(0, i));

Split the sentence using String.split and then iterate over the resulting array backwards. To split at whitespace do
test.split(" +");
The split method takes a Regular Expression and the above means: split at one or more consecutive whitespaces.
Recursive approach:
public String reverse(final String s) {
final int pos = s.indexOf(' ');
if (pos > -1) {
return reverse(s.substring(pos + 1).trim()) + " " + s.substring(0, pos).trim();
}
return s;
}

In this approach you can selectively create substring based on whitespace. For input This is a test. below method will give return test. a is This. Idea here is if you have a leading space, you will actually convert to trailing space.
public static String reverseString(String str) {
if (str.equals(""))
return "";
else {
int i = str.length() - 1;
while (!Character.isWhitespace(str.charAt(i))) {
if (i - 1 < 0)
break;
i--;
}
String substring;
if(Character.isWhitespace(str.charAt(i)))
{
substring= str.substring(i+1,str.length())+" ";
}
else
{
substring= str.substring(i,str.length());
}
return substring + reverseString(str.substring(0,i));
}
}

Working with your code you would just need to add an additional space in front of whatever string you want to reverse such as with this code
reverseString(" " + str)
when you first execute the method.

Related

how to find Length of Last Word in the given string using java?

Given a string s consists of some words separated by spaces, return the length of the last word in the string. If the last word does not exist, return 0.
**
'I am getting wrong answer as output Your input "Hello World" Output 1
Expected 5'
**
here is my solution
class Solution { public int lengthOfLastWord(String s) { if(s.length()==0) { return 0; } String words[]=null; words=s.split(""); String str=words[words.length-1]; return str.length(); } }
try this, here yo can get last word from string:
if (s == null || s.length() == 0) {
return 0;
} else {
String lastWord = s.substring(s.lastIndexOf(" ") + 1);
return lastWord.length();
}
Use words=s.split(" "); instead of words=s.split("");
Your delimiter should be a space.

Reverse the words in Java with recursively

public class PrintElements {
public static void printReverse (String str)
{
if ((str==null)||(str.length() <= 1))
System.out.print(str);
else
{
System.out.print(str.charAt(str.length()-1));
printReverse(str.substring(0,str.length()-1));
}
}
/**
* #param args
*/
public static void main(String[] args) {
String str="this function reverse";
printReverse(str);
}
}
In this method, I am trying to just change the place the words not letters place with using recursion.
For example, if "this function reverse" is the input, the output should be "Reverse function this".
But my current output is : "esrever noitcnuf siht"
Do it as follows:
import java.util.Arrays;
public class Main {
public static void printReverse(String str) {
if (str == null || !str.contains(" ")) {
System.out.print(str);
return;
}
String[] words = str.split("\\s+");// Split str on space(s)
System.out.print(words[words.length - 1] + " ");// Print the last element
// Call the method recursively by passing a new string with all but last word
printReverse(String.join(" ", Arrays.asList(words).subList(0, words.length - 1)));
}
public static void main(String[] args) {
String str = "this function reverse";
printReverse(str);
}
}
Output:
reverse function this
Try this. It traverses the input string and finds out each word and then merges them into the reversed string by reversing the order of the words.
public static void printReverse (String str)
{
if ((str == null) || (str.equals("")))
return ;
str = str + " "; //to add a space at the end. this will help in detecting the last word
String revStr = "", word = "";
char c;
for (int i=0; i < str.length(); i++)
{
c = str.charAt(0);
if (c != ' ')
{
word = word + c;
}
else
{
revStr = word + " " + revStr;
}
}
System.out.println(revStr.Trim()); //removes the extra space from the end
}
}
public static String reverseString(String str) {
if (str == null)
return "";
if (!str.contains(" "))
return str;
int whitespacePos = str.indexOf(" ");
String firstWord = str.substring(0, whitespacePos);
return reverseString(str.substring(whitespacePos + 1)) + " " + firstWord;
}
public static void main(String[] args) {
String str = "this function reverse";
System.out.println(reverseString(str));
}
I tested this code and it works
It is (most of the time) cleaner to return a String, and then print this String if you want to.
If you use charAt(), you are only getting individual characters. Therefore it will be difficult to not also reverse the letters of the words. It is easier to find the whitespaces between the words and then to retrieve whole words with subString()
the subString() method can take two parameters, startIndex and endIndex, or just one parameter, only the startIndex. It then returns the subString from this startIndex up to the end of the String.
Note: I know you can use split(), I wanted to show how it can be done with indexes. If you already use split(), you might aswell not use recursion.
public static void reverseWords(String str){
if(str=="" || str==null){
return;
}else {
String[] _str = str.split(" ");
System.out.println(_str[_str.length-1]);
String[] newArr = Arrays.copyOf(_str,_str.length-1);
reverseWords(String.join(" ", newArr));
}
}
dont forget to import
import java.util.Arrays;
public String reverseString(String str){
if(str.lastIndexOf(32) ==-1){ //32 is an ASCII value for space
return str;
}
return str.substring(str.lastIndexOf(32)+1)+" "+reverseString(str.substring(0,str.lastIndexOf(32)));
//Here lastIndexOf() method get the last element of space so that method substring takes the String after last space because is used lastIndexOf(32)+1 and
//reverseString() method continuously takes up to n-1 from nth string until lastIndexOf() return -1 i.e no more whitespace avaliable
}
Here's a solution:
public String reverseString(final String str){
//Using ternary operator
return (str.lastIndexOf(32) == -1)
? str
: str.substring(str.lastIndexOf(32) + 1) + " " + reverseString(str.substring(0, str.lastIndexOf(32)));
}
or with if-else:
public String reverseString(final String str){
if (str.lastIndexOf(32) == -1))
return str;
else
return str.substring(str.lastIndexOf(32) + 1) + " " + reverseString(str.substring(0, str.lastIndexOf(32)));
}
32 is the space character. So if there's no space in the string it just returns the string (word). If there is one it recursively swaps the tail after the and the word before it.

How to use recursion to create a searies of substrings in java

So, the task is to create a string that makes a progression throughout the letters of a string, returning a substring progressively longer.
For example if the input is Book, the answer would be: BBoBooBook . For the input Soup the method would return SSoSouSoup. I want to write it recursively. In my current method I receive no error but at the same time no anwer from the compiler.
public static String stringProgression(String str) {
int index = 1;
String result = "";
if (str.length() == 0) {
return "" ;
} else while (index <= str.length()); {
result = result + stringExplosion(str.substring(0, index));
index++;
}
return result;
}
In your code, you are using two different method names, stringProgression and stringExplosion.
Further, you have a while loop with a semicolon, while (index <= str.length()); which forms an empty loop. Since index doesn’t change in this empty loop, it will be an infinite loop when the condition is fulfilled.
Generally, a while loop contradicts the intent to have a recursive solution.
To find a recursive solution to a problem, you have to find the self-similarity in it. I.e. when you look at the intended result for Book, BBoBooBook, you can recognize that the beginning, BBoBoo is the right result for the string Boo, and BBo is the right result for Bo. So, the original string has to be appended to the result of a recursive evaluation of the substring:
public static String stringProgression(String str) {
if(str.isEmpty()) {
return str;
}
return stringProgression(str.substring(0, str.length() - 1)) + str;
}
An alternative, shorter syntax for the same is:
public static String stringProgression(String str) {
return str.isEmpty()? str: stringProgression(str.substring(0, str.length() - 1)) + str;
}
Check this one:
private static String doStringProgression(String str, String res, int length) {
if(length > str.length()) {
return res;
}
return doStringProgression(str, res + str.substring(0, length), length + 1);
}
And you can call the method with input like in the following example:
public static String stringProgression(String str) {
return doStringProgression(str, "", 1);
}

How do I find what's inbetween " " in an inputted string? [duplicate]

I'd like to retrieve whatever is in quotes that someone enters as a string, i'm assuming it's substring that I need but i'm not sure how.
When the user inputs a string mixed with words and numbers all separated by one space:
hey 110 say "I am not very good at Java" but " I can fish pretty well"
Then I want to be able to take the "I am not very good at Java" and the "I can fish pretty well" and print out what's inside the quotes so there can be multiple quotes in the string.
right now I have if( userInput=='"') then I do something with substring but i'm not sure what.
I can't use split, trim, tokenizer, regex or anything that would make this really easy unfortunatley.
it's all in this method where I try to identify if something in the string is a word, number or a quote:
public void set(String userInput)// method set returns void
{
num=0;// reset each variable so new input can be passed
String empty="";
String wordBuilder="";
userInput+=" ";
for(int index=0; index<userInput.length(); index++)// goes through each character in string
{
if(Character.isDigit(userInput.charAt(index)))// checks if character in the string is a digit
{
empty+=userInput.charAt(index);
}
else
{
if (Character.isLetter(userInput.charAt(index)))
{
wordBuilder+=userInput.charAt(index);
}
else
{
if(userInput.charAt(index)=='"')
{
String quote=(userInput.substring(index,);
}
}
//if it is then parse that character into an integer and assign it to num
num=Integer.parseInt(empty);
word=wordBuilder;
empty="";
wordBuilder="";
}
}
}
}
Thanks!
Try the next:
public static void main(String[] args) {
String input = "\"123\" hey 110 say \"I am not very good at Java\" but \" I can fish pretty well\"";
int indexQuote = -1;
boolean number = true;
String data = "";
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (Character.isWhitespace(ch)) {
if (data.length() > 0 && indexQuote == -1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
// reset vars
number = true;
data = "";
} else if (indexQuote != -1) {
data += ch;
}
} else if (ch == '"') {
if (indexQuote == -1) {
number = false;
indexQuote = i;
} else {
System.out.println("It's a quote: " + data);
// reset vars
number = true;
data = "";
indexQuote = -1;
}
} else {
if (!Character.isDigit(ch)) {
number = false;
}
data += ch;
if (data.length() > 0 && i == input.length() - 1) {
if (number) {
System.out.println("It's a number: " + data);
} else {
System.out.println("It's a word: " + data);
}
}
}
}
}
Output:
It's a word: hey
It's a number: 110
It's a word: say
It's a quote: I am not very good at Java
It's a word: but
It's a quote: I can fish pretty well
I'm not sure if this quite what you are looking for, but it will strip down the quoted parts in steps...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...";
if (quote.contains("\"")) {
while (quote.contains("\"")) {
int startIndex = quote.indexOf("\"");
int endIndex = quote.lastIndexOf("\"");
quote = quote.substring(startIndex + 1, endIndex);
System.out.println(quote);
}
}
Which outputs...
I have something to say, "It's better to burn out then fade away"
It's better to burn out then fade away
Updated
I don't know if this is cheating or not...
String quote = "I say: \"I have something to say, \"It's better to burn out then fade away\"\" outloud...\"Just in case you don't believe me\"";
String[] split = quote.split("\"");
for (String value : split) {
System.out.println(value);
}
Which outputs...
I say:
I have something to say,
It's better to burn out then fade away
outloud...
Just in case you don't believe me
Updated
Okay, fake String#split
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
System.out.println(sb);
sb.delete(0, sb.length());
} else {
sb.append(quote.charAt(index));
}
}
Updated
Okay, this is basically fake split with options...
String quote = "blah blah 123 \"hello\" 234 \"world\"";
boolean quoteOpen = false;
StringBuilder sb = new StringBuilder(quote.length());
for (int index = 0; index < quote.length(); index++) {
if (quote.charAt(index) == '"') {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
quoteOpen = false;
sb.delete(0, sb.length());
} else {
System.out.println("Text: [" + sb.toString() + "]");
sb.delete(0, sb.length());
quoteOpen = true;
}
} else {
sb.append(quote.charAt(index));
}
}
if (sb.length() > 0) {
if (quoteOpen) {
System.out.println("Quote: [" + sb.toString() + "]");
} else {
System.out.println("Text: [" + sb.toString() + "]");
}
}
Which generates...
Text: [blah blah 123 ]
Quote: [hello]
Text: [ 234 ]
Quote: [world]
Know, I don't know how you are storing the results. I would be tempted to create some basic classes which were capable of storing the String results and add them to a List so I could maintain the order and maybe use a flag of some kind to determine what type they are...
Iterate over the string and use a temporary int variable to store when the quoted string started. When you see that it ends, you can extract that substring and do what you want with it.
Use StringUtils.subStringBetween
public class MyTestSecond {
public static void main(String...args){
String a = "hey 110 say \"I am not very good at Java\"";
// Method 1
if(a.contains("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
//Method 2
String[] array = a.split(" ");
for(int i=0;i<array.length;i++){
if(array[i].startsWith("\""))
System.out.println(a.substring(a.indexOf("\""),a.lastIndexOf("\"")+1));
}
}
}
public String getNextQuote(int index, String sentence){
return sentence.substring(sentence.indexOf("\"", index + 1), sentence.indexOf("\"", index + 2));
}
usage: call the method with an index as parameter. This index resembles the index of the last " that you've encountered.
Afterwards, it will return everything between the next two quotes.

How to remove the last character from a string?

I want to remove the last character from a string. I've tried doing this:
public String method(String str) {
if (str.charAt(str.length()-1)=='x'){
str = str.replace(str.substring(str.length()-1), "");
return str;
} else{
return str;
}
}
Getting the length of the string - 1 and replacing the last letter with nothing (deleting it), but every time I run the program, it deletes middle letters that are the same as the last letter.
For example, the word is "admirer"; after I run the method, I get "admie." I want it to return the word admire.
replace will replace all instances of a letter. All you need to do is use substring():
public String method(String str) {
if (str != null && str.length() > 0 && str.charAt(str.length() - 1) == 'x') {
str = str.substring(0, str.length() - 1);
}
return str;
}
Why not just one liner?
public static String removeLastChar(String str) {
return removeLastChars(str, 1);
}
public static String removeLastChars(String str, int chars) {
return str.substring(0, str.length() - chars);
}
Full Code
public class Main {
public static void main (String[] args) throws java.lang.Exception {
String s1 = "Remove Last CharacterY";
String s2 = "Remove Last Character2";
System.out.println("After removing s1==" + removeLastChar(s1) + "==");
System.out.println("After removing s2==" + removeLastChar(s2) + "==");
}
public static String removeLastChar(String str) {
return removeLastChars(str, 1);
}
public static String removeLastChars(String str, int chars) {
return str.substring(0, str.length() - chars);
}
}
Demo
Since we're on a subject, one can use regular expressions too
"aaabcd".replaceFirst(".$",""); //=> aaabc
The described problem and proposed solutions sometimes relate to removing separators. If this is your case, then have a look at Apache Commons StringUtils, it has a method called removeEnd which is very elegant.
Example:
StringUtils.removeEnd("string 1|string 2|string 3|", "|");
Would result in:
"string 1|string 2|string 3"
public String removeLastChar(String s) {
if (s == null || s.length() == 0) {
return s;
}
return s.substring(0, s.length()-1);
}
Don't try to reinvent the wheel, while others have already written libraries to perform string manipulation:
org.apache.commons.lang3.StringUtils.chop()
In Kotlin you can used dropLast() method of the string class.
It will drop the given number from string, return a new string
var string1 = "Some Text"
string1 = string1.dropLast(1)
Use this:
if(string.endsWith("x")) {
string= string.substring(0, string.length() - 1);
}
if (str.endsWith("x")) {
return str.substring(0, str.length() - 1);
}
return str;
For example, the word is "admirer"; after I run the method, I get "admie." I want it to return the word admire.
In case you're trying to stem English words
Stemming is the process for reducing inflected (or sometimes derived) words to their stem, base or root form—generally a written word form.
...
A stemmer for English, for example, should identify the string "cats" (and possibly "catlike", "catty" etc.) as based on the root "cat", and "stemmer", "stemming", "stemmed" as based on "stem". A stemming algorithm reduces the words "fishing", "fished", "fish", and "fisher" to the root word, "fish".
Difference between Lucene stemmers: EnglishStemmer, PorterStemmer, LovinsStemmer outlines some Java options.
As far as the readability is concerned, I find this to be the most concise
StringUtils.substring("string", 0, -1);
The negative indexes can be used in Apache's StringUtils utility.
All negative numbers are treated from offset from the end of the string.
string = string.substring(0, (string.length() - 1));
I'm using this in my code, it's easy and simple.
it only works while the String is > 0.
I have it connected to a button and inside the following if statement
if (string.length() > 0) {
string = string.substring(0, (string.length() - 1));
}
public String removeLastChar(String s) {
if (!Util.isEmpty(s)) {
s = s.substring(0, s.length()-1);
}
return s;
}
removes last occurence of the 'xxx':
System.out.println("aaa xxx aaa xxx ".replaceAll("xxx([^xxx]*)$", "$1"));
removes last occurrence of the 'xxx' if it is last:
System.out.println("aaa xxx aaa ".replaceAll("xxx\\s*$", ""));
you can replace the 'xxx' on what you want but watch out on special chars
Look to StringBuilder Class :
StringBuilder sb=new StringBuilder("toto,");
System.out.println(sb.deleteCharAt(sb.length()-1));//display "toto"
// creating StringBuilder
StringBuilder builder = new StringBuilder(requestString);
// removing last character from String
builder.deleteCharAt(requestString.length() - 1);
How can a simple task be made complicated. My solution is:
public String removeLastChar(String s) {
return s[0..-1]
}
or
public String removeLastChar(String s) {
if (s.length() > 0) {
return s[0..-1]
}
return s
}
// Remove n last characters
// System.out.println(removeLast("Hello!!!333",3));
public String removeLast(String mes, int n) {
return mes != null && !mes.isEmpty() && mes.length()>n
? mes.substring(0, mes.length()-n): mes;
}
// Leave substring before character/string
// System.out.println(leaveBeforeChar("Hello!!!123", "1"));
public String leaveBeforeChar(String mes, String last) {
return mes != null && !mes.isEmpty() && mes.lastIndexOf(last)!=-1
? mes.substring(0, mes.lastIndexOf(last)): mes;
}
A one-liner answer (just a funny alternative - do not try this at home, and great answers already given):
public String removeLastChar(String s){return (s != null && s.length() != 0) ? s.substring(0, s.length() - 1): s;}
Most answers here forgot about surrogate pairs.
For instance, the character 𝕫 (codepoint U+1D56B) does not fit into a single char, so in order to be represented, it must form a surrogate pair of two chars.
If one simply applies the currently accepted answer (using str.substring(0, str.length() - 1), one splices the surrogate pair, leading to unexpected results.
One should also include a check whether the last character is a surrogate pair:
public static String removeLastChar(String str) {
Objects.requireNonNull(str, "The string should not be null");
if (str.isEmpty()) {
return str;
}
char lastChar = str.charAt(str.length() - 1);
int cut = Character.isSurrogate(lastChar) ? 2 : 1;
return str.substring(0, str.length() - cut);
}
Java 8
import java.util.Optional;
public class Test
{
public static void main(String[] args) throws InterruptedException
{
System.out.println(removeLastChar("test-abc"));
}
public static String removeLastChar(String s) {
return Optional.ofNullable(s)
.filter(str -> str.length() != 0)
.map(str -> str.substring(0, str.length() - 1))
.orElse(s);
}
}
Output : test-ab
public String removeLastCharacter(String str){
String result = null;
if ((str != null) && (str.length() > 0)) {
return str.substring(0, str.length() - 1);
}
else{
return "";
}
}
if we want to remove file extension of the given file,
** Sample code
public static String removeNCharactersFromLast(String str,int n){
if (str != null && (str.length() > 0)) {
return str.substring(0, str.length() - n);
}
return "";
}
For kotlin check out
string.dropLast(1)
if you have special character like ; in json just use String.replace(";", "") otherwise you must rewrite all character in string minus the last.
Why not use the escape sequence ... !
System.out.println(str + '\b');
Life is much easier now . XD ! ~ A readable one-liner
How to make the char in the recursion at the end:
public static String removeChar(String word, char charToRemove)
{
String char_toremove=Character.toString(charToRemove);
for(int i = 0; i < word.length(); i++)
{
if(word.charAt(i) == charToRemove)
{
String newWord = word.substring(0, i) + word.substring(i + 1);
return removeChar(newWord,charToRemove);
}
}
System.out.println(word);
return word;
}
for exemple:
removeChar ("hello world, let's go!",'l') → "heo word, et's go!llll"
removeChar("you should not go",'o') → "yu shuld nt goooo"
Here's an answer that works with codepoints outside of the Basic Multilingual Plane (Java 8+).
Using streams:
public String method(String str) {
return str.codePoints()
.limit(str.codePoints().count() - 1)
.mapToObj(i->new String(Character.toChars(i)))
.collect(Collectors.joining());
}
More efficient maybe:
public String method(String str) {
return str.isEmpty()? "": str.substring(0, str.length() - Character.charCount(str.codePointBefore(str.length())));
}
just replace the condition of "if" like this:
if(a.substring(a.length()-1).equals("x"))'
this will do the trick for you.
Suppose total length of my string=24
I want to cut last character after position 14 to end, mean I want starting 14 to be there.
So I apply following solution.
String date = "2019-07-31T22:00:00.000Z";
String result = date.substring(0, date.length() - 14);
I had to write code for a similar problem. One way that I was able to solve it used a recursive method of coding.
static String removeChar(String word, char charToRemove)
{
for(int i = 0; i < word.lenght(); i++)
{
if(word.charAt(i) == charToRemove)
{
String newWord = word.substring(0, i) + word.substring(i + 1);
return removeChar(newWord, charToRemove);
}
}
return word;
}
Most of the code I've seen on this topic doesn't use recursion so hopefully I can help you or someone who has the same problem.

Categories

Resources