reverse string recursive method - java

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

Related

Local linked lists can be changed by a method but local strings cannot, why? [duplicate]

I have this very awkward question...
void changeString(String str){
str = "Hello world":
}
main(){
String myStr = new String("");
changeString(myStr);
}
When main returns, the value is still "" and not "Hello world". Why is that?
Also, how do I make it work? Let's say I want my function changeString to change the string it got to "Hello world".
Everyone explained why it doesn't work, but nobody explained how to make it work. Your easiest option is to use:
String changeString() {
return "Hello world";
}
main() {
String myStr = new String("");
myStr = changeString();
}
Although the method name is a misnomer here. If you were to use your original idea, you'd need something like:
void changeString(ChangeableString str) {
str.changeTo("Hello world");
}
main() {
ChangeableString myStr = new ChangeableString("");
changeString(myStr);
}
Your ChangeableString class could be something like this:
class ChangeableString {
String str;
public ChangeableString(String str) {
this.str = str;
}
public void changeTo(String newStr) {
str = newStr;
}
public String toString() {
return str;
}
}
A quick lesson on references:
In Java method everything is passed by value. This includes references. This can be illustrated by these two different methods:
void doNothing(Thing obj) {
obj = new Something();
}
void doSomething(Thing obj) {
obj.changeMe();
}
If you call doNothing(obj) from main() (or anywhere for that matter), obj won't be changed in the callee because doNothing creates a new Thing and assigns that new reference to obj in the scope of the method.
On the other hand, in doSomething you are calling obj.changeMe(), and that dereferences obj - which was passed by value - and changes it.
Java uses a call by value startegy for evaluating calls.
That is, the value is copied to str, so if you assign to str that doesn't change the original value.
If the changing of your String happens very often you could also assign a StringBuffer or StringBuilder to your variable and change its contents and only convert it to a String when this is needed.
Expanding a bit on NullUserException's excellent answer, here's a more general solution:
public class Changeable<T> {
T value;
public Changeable(T value) {
this.value = value;
}
public String toString() {
return value.toString();
}
public boolean equals(Object other) {
if (other instanceof Changeable) {
return value.equals(((Changeable)other).value);
} else {
return value.equals(other);
}
}
public int hashCode() {
return value.hashCode();
}
}
Yura's original code can then be rewritten as:
void changeString(Changeable<String> str){
str.value = "Hello world":
}
void main() {
Changeable<String> myStr = new Changeable<String>("");
changeString(myStr);
}
And, just for fun, here it is in Scala:
class Changeable[T](var self: T) extends Proxy;
object Application {
def changeString(str: Changeable[String]): Unit = {
str.self = "Hello world";
}
def main(): Unit = {
val myStr = new Changeable("");
changeString(myStr);
}
}
Because the reference myStr is passed by value to the function changeString and the change is not reflected back to the calling function.
P.S : I am not a Java guy.
Bill, I have a solution to your problem which uses a List as a pointer in java!
void changeString(List<String> strPointer ){
String str = "Hello world";
strPointer.add(0, str);
}
main(){
LinkedList<String> list = new LinkedList<String>();
String myStr = new String("");
changeString(list);
myStr = list.get(0);
System.out.println( myStr );
}
This answer takes a little extra work to insert and get out the string from the list, however the final line will print "Hello world!"
I hope this can help others as well!
-Port Forward Podcast
Here's the one more solution by StringBuffer/StringBuilder worked for me.
static void changeValue(StringBuilder str){
str.append("newValue");
}
main(){
StringBuilder originalVal= new StringBuilder();
changeValue(originalVal);
System.out.println(originalVal.toString());
}

Java method taking 0 arguments and returning a double using if else statements with strings

I am trying to write a method which does not take any arguments and then returns a double variable. It is a postcode identifier so when a cost code is entered certain post codes need to return a double.
In my example below i need post codes that start with either "GH6 TXX" or "NC4 LXX". (X stands for any random character or digit) to return 50.0.
If any other postcode is entered then return 100.0.
However i am not getting any results back and just finding errors. I'm sure i have gone massive wrong somewhere as im not great with If Else statements within methods. Any help or knowledge on this would be great!
public class multiPostcodeRange {
//Declaring Variables
String pcode;
public multiPostcodeRange()
{
pcode = "XXX XXX";
}
public void multiPostcodeRange()
{
if (pcode("GH6 TXX", "NC4 LXX")) {
return 100.0; }
else {
return 50.0;}
} }
public class MultiPostcodeRange {
private String pcode;
public MultiPostcodeRange() {
pcode = "XXX XXX";
}
public double multiPostcodeRange() {
if (pcode.equals("GH6 TXX") || pcode.equals("NC4 LXX")) {
return 100.0;
}
else {
return 50.0;
}
}
}
To return double from a function you need to define a return type for the function.
public double multiPostcodeRange
You created a class with his methods (which btw you shouldn't name as the class, but give them unique names).
Then you have to create a new instance object of that class and call the method on a main function.
For example, at the end of your code:
`public static void main(String args[]){
multiPostcodeRange Obj = new
multiPostcodeRange();
Obj.meth1();
Obj.meth2();}`
NB remember to give those methods unique names!
Also change 2nd method body and type as AndyMan's answer

Problem with recursive method in reversing the string

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);
}

Call boolean method statically from separate class

I have a program that takes letters for input and then sums the numeric value of each letter.
I have it so that if I input "abc", my output is "6".
I ignore uppercase letters, so if I input "abC", my output is "3".
What I want to do now, is in a separate class, make a method, which if set to true will run my main program as is, but when it is set to false, it will treat uppercase letters as lowercase, giving an input of "abC", an output of "6".
I hope this makes sense, I've tried a few different things but they all run the programm as is, ignoring uppercase.
Here is my code, I appreciate any constructive feedback.
Thanks
EDIT: I would also appreciate if you didn't downvote me for asking a question, if you don't want to help dont', seems every question I asked gets downvoted for no obvious or fair reason. I didn't want to ask for help since I knew this would happen. We all start have to somewhere!
Main method:
Scanner scan = new Scanner(System.in);
System.out.println("\nPlease enter the letters you would like to use:");
String s, t = "";
scan.next();
s = scan.next();
boolean b = Converter.caseSensitive(false, s);
scan.close();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (!t.isEmpty()) {
t += ",";
}
if (ch >= 'a' && ch <= 'z') {
int n = ch - 'a' + 1;
t += String.valueOf(n);
}
}
Second method in separate class:
public class Converter {
public static boolean caseSensitive(Boolean b, String s) {
for (char c : s.toCharArray()) {
if (Character.isLetter(c) && Character.isLowerCase(c)) {
b = s.equalsIgnoreCase(s);
return false;
}
}
s = s.toLowerCase();
return true;
}
}
I believe your question is "how do I record a static boolean value in a class and then request it from another class?"
public class Configuration {
private static boolean convertToUppercase = true;
public static void setConvertToUppercase(boolean convert) {
convertToUppercase = convert;
}
public static boolean getConvertToUppercase() {
return convertToUppercase;
}
}
This can be used as:
StringConverter.caseSensitive(Configuration.getConvertToUppercase(), input);
Note that most coders (me included) would consider this poor design but explaining why is outside the scope of your question.
There are a lot of other issues with your code. For example your method call above will leave the input string unchanged. But I suggest you ask another question with just the relevant code when you get stuck.
String is immutable in Java. Please read following stackoverflow question for more information about this topic:
String is immutable. What exactly is the meaning?
public static void main(String[] args) throws Exception
{
String test = "abc";
toUpperCase(test);
System.out.println(test);
}
private static void toUpperCase(String test)
{
test = test.toUpperCase();
}
Please note that above code will output:
abc
In order to have "ABC" as result you need to use following code:
public static void main(String[] args) throws Exception
{
String test = "abc";
test = toUpperCase(test);
System.out.println(test);
}
private static String toUpperCase(String test)
{
return test.toUpperCase();
}
This one outputs:
ABC
So your Converter.caseSensitive method should return String.
I don't think you really need the Converter class. You can delete class and replace the line:
boolean b = Converter.caseSensitive(false, s);
with this
boolean shouldCountUppercaseLetters = false;
if (shouldCountUppercaseLetters) {
s = s.toLowerCase();
}

java program with methods and boolean

import java.util.Scanner ;
public class ProcessNumbers
{
public static void main( String[] args )
{
Scanner in = new Scanner(System.in) ;
System.out.print("Please enter an integer between 6 and 12, inclusive: ") ;
int num = in.nextInt() ;
boolean result = shouldProcess(num);
String result1 = String.valueOf(result) ;
}
public static boolean shouldProcess(int n)
{
if (n>=6 && n<12)
{
return true;
}
else
{
return false;
}
}
public static boolean processInput(boolean result2)
{
if (result2 == true)
{
System.out.println("Yes") ;
}
else
{
System.out.println("No") ;
}
return result2 ;
}
}
now I am getting the output which is partially right but has forgot the yes or no output in the second method
Please enter an integer between 6 and 12, inclusive:
when it should also include the yes or not output
You are sending in a boolean value in the method parameter of processInput but you are catching it as a String. You need to change it to boolean. Further, you want to check if its value is true with equal signs like below:
public static void processInput(boolean result2)
{
if (result2 == true)
{
System.out.println("Yes") ;
}
else
{
System.out.println("No") ;
}
}
EDIT 2:
Also, you need to change String result1 = String.valueOf(result); to processInput(result);
EDIT 3:
If you want the number printed too that you just entered and then you want a "yes" or "no", then between int num = in.nextInt(); and boolean result = shouldProcess(num);, add this line: System.out.println(num);
There's apparently some code missing, so I'm guessing this is just part of the full thing. So I will only tackle your output issue.
I won't talk about the code in: public static boolean processInput(boolean result2), because you're not running it anywhere in your main method public static void main( String[] args ) anyway.
Now, in your code at:
public static boolean shouldProcess(int n)
if you look at your code, you are assigning the value of the boolean to the new String result1, so result1 now has the new value, but you are not running its output anywhere, so there's no way the program can guess you want to output that value. You need to assign the output:
System.out.print(result1);
However, if you only want to output the boolean, there's no need to assign that boolean value to a new String and then output the new String, you could just:
System.out.print(result);
Unless you're going to use that value somewhere else where creating a new variable would arguably be a good choice.
Also, it seems you want to return either a "Yes" or "No" on your class: public static boolean processInput(boolean result2).
Remember a class that does not return a value, but rather executes a code, has to be written as void. In other words, your:
public static boolean processInput(boolean result2)
should really be:
public static void processInput(boolean result2)
Because if not, you are just making your program return result2;, which in this case can only be either true or false. By adding void to the class, makes the class understand it will be executing your System.out.print code, rather than returning a value for you to use. But also, depends on what you want to afterwards.

Categories

Resources