Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have written a program to reverse the words in a string.
if i/p is "The dog is chasing"
then o/p should be "chasing is dog The"
public class String_reverse {
public static void main(String[] args) {
String input= "The dog is chasing";
String[] arr= input.split(" ");
String reverse="";
for(int i=arr.length-1;i>=0;i--)
{
reverse+= ((reverse.equals(""))?"":" ")+arr[i];
}
System.out.println(reverse);
}
}
But I don't know how to write this program using recursion. When I tried searching in stackoverflow, I could find reversing a string; but not reversing the words in a string.
Recursive method, using same logic as linked "duplicate", without use of split():
private static String reverseWords(String text) {
int idx = text.indexOf(' ');
return (idx == -1 ? text : reverseWords(text.substring(idx + 1)) + ' ' + text.substring(0, idx));
}
The logic is:
Take first char/word
If that is last char/word, return with it
Perform recursive call with remaining text (excluding word-separating space).
Append space (if doing word)
Append first char/word from step 1
Return result
As you can see, when applied to reversing text (characters) instead of words, it's very similar:
private static String reverseText(String text) {
return (text.length() <= 1 ? text : reverseText(text.substring(1)) + text.charAt(0));
}
For people who like things spelled out, and dislike the ternary operator, here are the long versions, with extra braces and support for null values:
private static String reverseWords(String text) {
if (text == null) {
return null;
}
int idx = text.indexOf(' ');
if (idx == -1) {
return text;
}
return reverseWords(text.substring(idx + 1)) + ' ' + text.substring(0, idx);
}
private static String reverseText(String text) {
if (text == null || text.length() <= 1) {
return text;
}
return reverseText(text.substring(1)) + text.charAt(0);
}
Notice how the long version of reverseText() is exactly like the version in the linked duplicate.
Recursive methods could seem a bit hard when beginning but try to do the following :
Simplify the problem as much as possible to find yourself with the less complicated case to solve. (Here for example, you could use a sentence with two words).
Begin with doing it on a paper, use Pseudocode to help you dealing with the problem with the simplest language possible.
Begin to code and do not forget an escape to your recursion.
Solution
public static void main(String[] args) {
String s = reverseSentence("This sentence will be reversed - I swear".split(" "));
System.out.println(s);
}
public static String reverseSentence(String[] sentence){
if (sentence.length <= 1){
return sentence[0];
}
String[] newArray = new String[sentence.length-1];
for (int i = 0 ; i < newArray.length ; i++){
newArray[i] = sentence[i];
}
return sentence[sentence.length-1] + " " + reverseSentence(newArray);
}
This is a sample program which will do what you want recursively:
public class ReverseWords {
public static void main(String args[]) {
String s = "This is a test";
reverse(s);
}
private static void reverse(String s) {
if(s == null) return;
String words[] = s.split(" ", 2);
if (words.length < 2) reverse(null);
else reverse(words[1]);
System.out.print(words[0] + " ");
}
}
You can refer to the following code.
class ReverseString {
public static void main(String args[]) {
String myString = "The dog is chasing";
reverse(myString);
}
public static String reverse(String myString) {
int space = myString.indexOf(" ");
if (space != -1) {
reverse(myString.substring(space + 1, myString.length()));
}
if (space == -1) {
System.out.println(myString.substring(0, myString.length()));
} else {
System.out.println(myString.substring(0, space));
}
return myString;
}
}
Related
I want to create a refactorSeparators method that takes an object of the String type as an argument. Method returns the text from the input object corrected so that if there is any
a comma or a period and there is no space after it, it will insert this space.I'm stuck, don't know what to do next, below is my code. How can I finish it? I wonder how to write this part: if (s.equals(".") && i.next().equals())
public class Separator {
public static void main(String[] args) {
String text = "Periods,hyphens, the last two characters cannot be a period. The rest of them don't. And there you go.";
ArrayList<String> stringArr = new ArrayList<>();
String[] arrOfStr = text.split("");
Iterator i = stringArr.iterator();
for (String s : arrOfStr) {
stringArr.add(s);
System.out.println("{" +s + "}");
}
for (String s : arrOfStr) {
if (s.equals(".") && i.next().equals()) {
String space = " ";
stringArr.add(i.next(, " ");
} else {
System.out.println("error");
}
}
}}
You're over-thinking it:
String refactorSeparators(String str) {
return str.replaceAll("([,.]) ?", "$1 ").trim();
}
The regex ([,.]) ? matches a comma or dot optionally followed by a space, which is replaced with the dot/comma and a space. The trim() removes the space that would be added if there's a dot at the end of the input.
Your main problem is here:
Iterator i = stringArr.iterator();
// ...
for (String s : arrOfStr) {
if (s.equals(".") && i.next().equals()) {
You are iterating both with an iterator and a for-loop, that makes life complicated. I'd suggest using a for-loop over the index.
Also your second equals expression is missing an argument.
Since Bohemian already posted the regex one liner, I might as well post my solution too:
public class PunctuationFixer {
private String text;
private int index;
public static String addMissingWhitespaceAfterPunctuation(String input) {
return new PunctuationFixer(input).fix();
}
private PunctuationFixer(String input) {
this.text = input;
this.index = 0;
}
private String fix() {
while (index < this.text.length() - 1) {
fix(this.text.charAt(index));
index++;
}
return this.text;
}
private void fix(char current) {
if (current == '.' || current == ',') {
addSpaceIfNeeded();
}
}
private void addSpaceIfNeeded() {
if (' ' != (text.charAt(index + 1))) {
text = text.substring(0, index + 1) + " " + text.substring(index + 1);
index++;
}
}
public static void main(String[] args) {
String text = "Periods,hyphens, the last two characters cannot be a period. The rest of them don't. And there you go.";
System.out.println(addMissingWhitespaceAfterPunctuation(text));
}
}
That's an typical parse issue. You have to remember the last char you've read and deppendend on your current char, you know what to do.
public static void main(String[] args) {
String text = "Periods,hyphens, the last two characters cannot be a period.The rest of them don't. And there you go.";
StringBuilder fixedString = new StringBuilder();
String[] arrOfStr = text.split("");
String lastChar = null;
for(String currentChar : arrOfStr) {
if(lastChar != null && (lastChar.equals(",") || lastChar.equals(".")) && !currentChar.equals(" "))
fixedString.append(" ");
fixedString.append(currentChar);
lastChar = currentChar;
}
System.out.println(fixedString);
}
Side note: The shortest and most elegant solution is, of course, #bohemian's. But I suspect it is not in the sense of the homework! ;-)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I need to print a String letter by letter with a * between each letter.
I want to find a recursive solution and not an iterative one. The signature must be :
public static String allStar(String a);
Beshambher's answer is a neat and easy way to do it. But if you want to do it recursively then :
public static String allStar(String a) {
if(a == null || a.isEmpty()) {
return "";
}
if(a.length() == 1) {
return a;
}
return a.charAt(0) + "*" + allStar(a.substring(1));
}
Try this where first the string is split into array of strings of each character and then joined together with a * character in between them.
System.out.println(String.join("*", a.split("")));
try this code :
public class Main {
static String Answer = "" ;
public static void main(String[] args) {
Main.SetStarAfterEachLetter("hello!");
System.out.println(Answer);
}
public static void SetStarAfterEachLetter(String letter){
Answer = Answer + letter.charAt(0);
Answer = Answer + " * ";
letter = letter.substring(1);
if(!letter.isEmpty()) {
SetStarAfterEachLetter(letter);
}
}
}
this is more general answer :
import java.util.Scanner;
public class Main {
static String Answer = "" ;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String word = scanner.nextLine();
Main.SetStarAfterEachLetter(word);
System.out.println(Answer);
}
public static void SetStarAfterEachLetter(String letter){
Answer = Answer + letter.charAt(0);
Answer = Answer + " * ";
letter = letter.substring(1);
if(!letter.isEmpty()) {
SetStarAfterEachLetter(letter);
}
}
Example implementation using overloaded functions addStar(String str) and addStar(int pos, String str):
public static String addStar(String str) {
if (null == str || str.isEmpty()) {
return str;
}
return addStar(0, str);
}
static String addStar(int pos, String str) {
if (pos == str.length() - 1) {
return Character.toString(str.charAt(pos));
}
return str.charAt(pos) + "*" + addStar(pos + 1, str);
}
Tests
System.out.println(addStar(null));
System.out.println("'" + addStar("") + "'");
System.out.println(addStar("a"));
System.out.println(addStar("ab"));
System.out.println(addStar("abcd"));
Output
null
''
a
a*b
a*b*c*d
Solution for recursive print a string
public static void allStar(String a) {
if (a != null && !a.isEmpty()) {
System.out.print(a.charAt(0));
if (a.length() > 1) {
System.out.print('*');
allStar(a.substring(1));
}
}
}
Solution for recursive build a string
public static void allStar(String a, StringBuilder builder) {
if (a != null && !a.isEmpty()) {
builder.append(a.charAt(0));
if (a.length() > 1) {
builder.append('*');
allStar(a.substring(1), builder);
}
}
}
For reducing heap pollution, this one is the best for recursive string build
public static void allStar(String a, int position, StringBuilder builder) {
if (a != null && position < a.length()) {
builder.append(a.charAt(position));
if (++position < a.length()) builder.append('*');
allStar(a, position, builder);
}
}
Use this for print recursivly builded string
public static void main(String[] args) {
StringBuilder builder = new StringBuilder();
allStar("test", 0, builder);
System.out.print(builder);
}
Solution with recursions not recommended, but possible for this task.
class AllStar {
public static String allStar(String a){
return allStar(0, a, "");
}
public static String allStar(int ch, String a, String res){
if(a.length() == 0){
return res;
}
if(ch == a.length() - 1){
res += a.charAt(ch);
return res;
}
else{
res += a.charAt(ch) + "*";
return allStar(ch + 1,a,res);
}
}
public static void main(String args[]){
System.out.println(allStar("aritro"));
}
}
Explanation :
We pass in the starting character index in the ch argument. a takes in the String which is to be printed according to the specified format, i.e., with stars. res takes in the String where the result should be stored. The if-statement checks if the letter is the last one. If true, it just appends the letter without a star to the res String as it is specified that stars should be between letters. It also returns the formatted String stored in res. If it is not the last letter, ch is incremented, the original String is passed as it is, and the formatted String is passed on as well. This continues till the last character is reached.
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.
I want to remove every second character from a string using the recursive method.
public static void main(String[] args) {
System.out.println(everySecond("wonderful"));
}
public static String everySecond(String s) {
if (s.length() % 2 != 0 ) {
System.out.print(s.substring(0,1));
}
if (s.length() <= 1) {
return s;
}
else {
String simpler = everySecond(s.substring(1))+ s.charAt(0);
return "";
}
}
}
Currently the program does what I need.
However, I want to include everything in the sub-recursive call String simpler = everySecond(s.substring(1))+ s.charAt(0); return ""; and remove code below.
if (s.length() % 2 != 0 ) {
System.out.print(s.substring(0,1));
}
I am fairly new to Java so I apologize if the answer is obvious. I assume I am overlooking some very basic solution here.
If the remaining length of the String is < 2 then we don't need to find any more characters to skip over. Otherwise, we need the initial character and then the rest of the String after the second character(the skipped one), therefore I did it like this:
public static String removeEverySecondChar(String str) {
if(str.length() < 2) {
return str;
}
return str.substring(0,1) + removeEverySecondChar(str.substring(2));
}
Input: Wonderful
Output: Wnefl
One of my AP projects includes separating each word from a string, I have tried accomplishing numerous times yet with no success! My class has not yet learned about arrays, regex, or split yet so if you could help please avoid any of those. However we did learn substring, charAt, indexOf, length, trim ...
This is one of my attempts:
(notice that in order for me to actually notice I've split them I try adding N to the string I am re-creating, which is newWord)
public class Functions {
public static String stringReversal(String word){
if (word.length() <= 1){
return word;
}else{
char c = word.charAt(0);
return stringReversal(word.substring(1)) + c;
}
}
public static Boolean palindrome(String word){
Boolean palindrome;
if (word.equalsIgnoreCase(stringReversal(word))){
return palindrome = true;
} else{
return palindrome = false;
}
}
public static String pigLatin(String sentence){
if(sentence.length() <= 1){
return sentence;
} else {
String newWord = "";
return newWord += pigLatin(sentence.substring(0, sentence.indexOf(" "))) + " N ";
}
}
}
Main:
public class Main {
public static void main (String [] args){
Scanner in = new Scanner(System.in);
String word = in.nextLine();
System.out.println(Functions.test(word));
}
}
However the output only print N! Can anyone please help and show a way that I can accomplish this, I've tried many ideas yet none worked.
Since this seems to be highly homework-related, I will only post some hints and suggestions, you will have to combine my hints and suggestions to come up with the/a solution yourself.
I believe this:
sentence.indexOf("")
should be this: sentence.indexOf(" ")
Checking indexOf an empty string makes not much sense (it always returns zero, since the empty string can be found everywhere within a String).
public static void main(String[] args) {
String word = "a bit of words";
System.out.println(test(word));
}
public static String test(String sentence){
if(sentence.length() <= 1){
return sentence;
} else {
String newWord = "";
return newWord += test(sentence.substring(0, sentence.indexOf(" "))) + " N ";
}
}
The above prints: a N
However, if your input is only one word then sentence.indexOf(" ") will return -1. You will need to check this. Suggestion: Modify your if-statement to instead check if string contains a space character or not.
To solve the assignment, you will need some kind of loop (recursion can also be a kind of loop) to repeat a slightly modified process for each word. Hint: Fetch the first word, then fetch the original String except for the extracted word.
public static void main( String[] args )
{
Scanner in = new Scanner( System.in );
try
{
while( true )
{
String word = in.nextLine();
System.out.println( splitWords( word ) );
}
}
finally
{
in.close();
}
}
private static String splitWords( String s )
{
int splitIndex = s.indexOf( ' ' );
if( splitIndex >= 0 )
return s.substring( 0, splitIndex ) + " N " + splitWords( s.substring( splitIndex + 1 ) );
return s;
}
you can use standard method String#split()
String[] words = sentence.split(' ');
note than words is an array