When I am reversing a String using the recursive method it is giving me the stackOverflow Error.
public class ReverseString {
public static void main(String[] args) {
String str = "Juhi";
System.out.println(recursiveString(str));
}
static String recursiveString(String str) {
return !str.equals("") ? recursiveString(str.substring(1) + str.charAt(0)) : str;
}
}
This should fix the problem:
static String recursiveString(String str) {
return !str.equals("") ? recursiveString(str.substring(1)) + str.charAt(0) : str;
}
In your code, you're not reducing the length of the string parameter, it's always the same input, so basically it's entering into an infinite loop. If we move the concatenation part after the recursive call, then the string will be shorter for each recursive call, until it's empty, signalling the end of the recursion.
public static void main(String[] args) {
String str = "Juhi";
System.out.println(recursiveString(str));
}
static String recursiveString(String str) {
return !str.equals("") ? recursiveString(str.substring(1) ) + str.charAt(0): str;
}
}
A Unicode-aware recursive reverse
While the other answers have shown you where you went wrong and how to write a recursive string reversing algorithm that works for basic Unicode characters, they produce wrong results for supplementary Unicode characters. The following method works for all Unicode characters:
static String recursiveReverse(String str) {
if (str.isEmpty())
return "";
int offsetToSecondCodePoint = str.offsetByCodePoints(0,1);
return recursiveReverse(str.substring(offsetToSecondCodePoint))
+ str.substring(0, offsetToSecondCodePoint);
}
Related
I'm trying to remove every sequence of () in my string.
For example my String is:
String a = "() a)";
And I want it to become
" a)"
When I tried this it gave me an infinite loop
public static String removeParentheses(String s) {
while (s.contains("()")) {
s = s.replaceAll("()", "");
}
return s;
}
String replaceAll method require regexp in parameter. In your case you provide empty group. To use string as parameter you can use replace method like:
public static void main(String[] args) {
String toChange = "asa()assaa()ass()asa()";
String result = toChange.replace("()", "");
assert Objects.equals(result, "asaassaaassasax");
}
Or change the regexp to correct form using \ character in way:
public static void main(String[] args) {
String toChange = "asa()assaa()ass()asa()";
String result = toChange.replaceAll("\\(\\)", "");
assert Objects.equals(result, "asaassaaassasax");
}
According the documentation of String.replaceAll, the first argument is a regular expression.
This means () is not being treated literally, it's being treated as an empty capture group, which effectively matches nothing. I think what you're looking for is the normal String.replace method. I'm aware that the names of these methods seem to imply that replace only replaces one instance while replaceAll replaces all of them, but this is not the case.
public static String removeParentheses(String s) {
return s.replace("()", "");
}
JDoodle deomonstrating code above
If for some reason you would like to continue using replaceAll instead, you can dynamically escape the pattern using Pattern.quote.
public static String removeParentheses(String s) {
String pattern = Pattern.quote("()");
return s.replaceAll(pattern, "");
}
JDoodle demonstrating code above
I am trying to solve a question where I need to remove specific substring from string using recursion.
I was able to solve this using a do while loop but that is not the best approach.
For example,
Suppose I have a string named, DADDAUUPPA and if I am given set of substrings like "DD", "UU","PP", "AA" then the returned string should be DA because, DADDAUUPPA -> DAAUUPPA -> DUUPPA -> DPPA -> DA
Here is my solution doing it using while loop.
String s = "DADDAUUPPA";
do{
String original = s;
return original.replace("DD","").replace("UU","").replace("PP","").replace("AA","" );
} while(!original)
Other challenging task is what if we are given these substrings as an array, how would we do it then?
For example,
public soln (String[] sub) {
// sub contains all the substring to be removed
}
Here is a solution
import java.util.LinkedList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> subs = new LinkedList<>();
subs.add("DD");
subs.add("AA");
subs.add("UU");
subs.add("PP");
String result = getSubString(subs, "DADDAUUPPA ");
System.out.print(result);
}
private static String getSubString(List<String> subs, String myString) {
if(subs !=null && subs.size() != 0) {
String sub = subs.get(0);
subs.remove(0);
myString = getSubString(subs, myString.replace(sub, ""));
}
return myString;
}
}
Key thing to learn is
private static String getSubString(List<String> subs, String myString) {
if(subs !=null && subs.size() != 0) {
myString = myString.replace(subs.get(0), "");
subs.remove(0);
getSubString(subs, myString);
}
return myString;
}
This does not work, note the difference between first and second getSubString method. As the stack unwinds myString gets assigned to original value.
I'm trying to write a method to take in a string as a parameter and remove all whitespaces and punctuation from it so this is my idea of how to do that..
import java.util.*;
public class Crypto {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.print("Please insert the text you wish to encrypt: ");
String text = input.nextLine();
text = normalizeText(text);
System.out.println(text);
}
public static String normalizeText(String s){
s.replace(" ","");
s.replace("(","");s.replace(")","");s.replace(".","");
s.replace(",","");s.replace("?","");s.replace("!","");
s.replace(":","");s.replace("'","");s.replace("\"","");
s.replace(";","");
s.toUpperCase();
return s;
}
}
Now , I only added the text = normalize Text(text); and then printed it because it wouldn't print it to the screen without it( even though in some methods the return would actually show an output on the screen)
anyway, even this change didn't help because it doesn't remove anything from the string taken in by the method it prints out the exact same string.. any help?
Thanks in advance . :)
Problem in your code is, you haven't assigned back the new string that got generated after s.replace(":",""); Remember, strings are immutable so the change by replace method will not apply to the string object on which you call the method.
You should have written,
s = s.replace(":", "")
Instead of your tedious method normalizeText you can write your method like this,
public static String normalizeText(String s){
return s.replaceAll("[ ().,?!:'\";]", "").toUpperCase();
}
You need to make assignments to the string after each replacement has been made, e.g.
public static String normalizeText(String s) {
s = s.replace(" ", "");
s = s.replace("(","");
// your other replacements
s = s.toUpperCase();
return s;
}
But note that we can easily just use a single regex to handle your replacement logic:
public static String normalizeText(String s) {
s = s.replaceAll("[().,?!:'\"; ]", "").toUpperCase();
return s;
}
Is it possible to get substring from right hand hand(Reverse) direction using substring() in JAVA.
Example.
Suppose String S="abcdef",
Can I get Substring "fedc" using S.substring(S.length()-1,3) ?
If it is not correct, please suggest me how to get Substring from right hand end(Reverse direction)??
You could reverse the string and use substring. Unfortunately String does not have that, but StringBuilder has it e.g.
new StringBuilder("abcdef").reverse().toString().substring(0,4);
You can reverse the string and find the substring
// reverse
String s = "abcdef";
StringBuilder builder = new StringBuilder(s);
String substring = builder.reverse().substring(0,3);
Java doesn't support extension methods like C# does, so I would build a function for this. This way you can control how much of the reverse substring you want with a parameter.
public class StackOverflow {
public static void main(String[] args) {
String data = "abcdef";
for (int i = 0; i < data.length(); i++) {
System.out.println(reverseSubstring(data, i+1));
}
}
public static String reverseSubstring(String data, int length) {
return new StringBuilder(data).reverse().substring(0, length);
}
}
Result:
f
fe
fed
fedc
fedcb
fedcba
UPDATE
Another approach is to create a wrapper class to String. This way you can call a class method like how you're asking in your question with the example S.substring(S.length()-1,3). This will also allow you to still have all the String methods after using the wrapper's get() method.
String Wrapper
public class MyString {
private String theString;
public MyString(String s) {
theString = s;
}
public String get() {
return theString;
}
public String reverseSubstring(int length) {
return new StringBuilder(theString).reverse().substring(0, length);
}
}
Usage
public class StackOverflow {
public static void main(String[] args) {
MyString data = new MyString("abcdef");
for (int i = 0; i < data.get().length(); i++) {
System.out.println(data.reverseSubstring(i+1));
}
}
}
Results:
f
fe
fed
fedc
fedcb
fedcba
Hello
Why my reverse method that uses recursion isn't working?
The print statement shows that the operation is done correctly but at the end it seems like only the very ast char of the entire String is assigned to h.
public static String reverse(String s,String h){
if(s.length()==0){
return s;
} else {
h+=s.charAt(s.length()-1);
System.out.println(h);//FOR TEST
s=s.substring(0,s.length()-1);
reverse(s,h);
return h;
}
}
Any advice?
Use
return reverse(s,h);
instead of
return h;
i.e:
public static String reverse(String s,String h){
if(s.length() == 0){
return h;
} else {
h+=s.charAt(s.length()-1);
System.out.println(h);//FOR TEST
s=s.substring(0,s.length()-1);
return reverse(s,h); //NOTICE THE CHANGE HERE,
}
}
Strings in Java are immutable. So in this code:
private static void foo(String x) {
x += "bar";
}
public static void main() {
String a = "foo";
foo(a);
System.out.println(a);
}
Only "foo" will be printed. It works the same way as if the type were int.
So your reverse function needs to do something with the return value. When you call reverse(s,h) you are throwing away the return value from the recursive call. You need to incorporate it:
String rec = reverse(s,h);
return ... something involving rec ...;
2 things:
public static String reverse(String s,String h){
if(s.length()==0){
return h; /// This needs to return the reversed string (h).
} else {
h+=s.charAt(s.length()-1);
System.out.println(h);//FOR TEST
s=s.substring(0,s.length()-1);
h = reverse(s,h); /// You need to use the return value
return h;
}
}
It looks like you were trying to change h using a return-by-reference-parameter. You have to remember that in Java everything (including references to objects) is passed by value. Once you write s=s.substring(0,s.length()-1);, s becomes a reference to a different String object, and that change is not propagated to the calling function.
Also, there is a way to implement this with only one input parameter.
I think this way is better for reversing a string using a recursive method :
public class Reversestringbyrecursivefunction {
public static void main(String[] args)
{
Scanner input=new Scanner(System.in);
while(true)
{
System.out.print("[?] Enter String('q' for exit)> ");
String str=input.next();
if(str.equals("q"))
break;
System.out.println("this string created by reversed recursive function : "+revers(str));
System.out.print("\n==========================\n");
}
System.out.print("\n\n\t\t\t[ GOOD LUCK!!! ]\n");
}
static String revers(String str)
{
if(str.length()<=1)
return str;
else
return revers(str.substring(str.length()-1, str.length()))+revers(str.substring(0, str.length()-1));
}
}
but , for best performance you should change this line :
return revers(str.substring(str.length()-1, str.length()))+revers(str.substring(0, str.length()-1));
to :
return str.substring(str.length()-1)+revers(str.substring(1, str.length()-1)+str.substring(0,1);
in prior line: in best performance and in one stage you can swap only 1 character of input string . but , in new line: in one stage you can swap 2 character of input string