recursive function returning a string of moves - java

Hey everyone I started doing recursion and I have to say its confusing me.
Currently I'm working on the Towers of Hanoi:
public static String hanoi(int n, int startPole, int endPole) {
String ret = new String();
if (n == 0){
return "";
}
int intermediatePole = 6 - startPole - endPole;
String add3 = hanoi(n-1, startPole, intermediatePole);
String add = startPole + "->" + endPole + "\n";
String add2 = hanoi(n-1, intermediatePole,endPole );
return add + add3 + add2;
}
So pretty much what's breaking my brain is - Who does one return the string of moves such that you get from a call of hanoi(2, 1, 3), you get a output like so, mine only returns one loop of the recursive call
1 - 3
1 - 2
3 - 2
1 - 3
2 - 1
2 - 3
1 - 3

Try it with return add3 + add + add2;. If your code's output is tried on a physical tower, it doesn't work.
The reason that you are only seeing "one loop of the recurisve call" is that the output show is actually for hanoi(3,1,3), not 2,1,3.

Related

How to split a string into 2 equal parts in Java

I want to divide a string like this:
String = "Titanic";
into two strings of equal length, and if it isn't divisible by 2 it will have 1 letter or extra on first or second part. like this
//if dividle by 2
Str1 = "BikG";
Str2 = "amer";
//if it isnt dividle by 2
Str1 = "Tita";
Str2 = "nic";
You can do it for example like this:
String base = "somestring";
int half = base.length() % 2 == 0 ? base.length()/2 : base.length()/2 + 1;
String first = base.substring(0, half);
String second = base.substring(half);
Simply when n is the string's length, if n is divisible by 2, split the string in n/2, otherwise split in n/2 + 1 so that first substring is one character longer than second.
What do you do to divide an odd number e.g. 15 with the same requirement?
You store the result of 15 / 2 into an int variable say
int half = 15 / 2
which gives you 7. As per your requirement, you need to add 1 to half to make the first half (i.e. 8) and the remaining half will be 15 - 8 = 7.
On the other hand, in case of an even number, you simply divide it by 2 to have two halves.
You have to apply the same logic in the case of a String as well. Given below is a demo:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int half;
String str1 = "Titanic";
half = str1.length() / 2;
String str1Part1 = str1.substring(0, half + 1);
String str1Part2 = str1.substring(half + 1);
System.out.println(str1Part1 + ", " + str1Part2);
String str2 = "HelloWorld";
half = str2.length() / 2;
String str2Part1 = str2.substring(0, half);
String str2Part2 = str2.substring(half);
System.out.println(str2Part1 + ", " + str2Part2);
Scanner in = new Scanner(System.in);
do {
System.out.print("Enter a string: ");
String str = in.nextLine();
half = str.length() / 2;
System.out.println(str.length() % 2 == 1 ? str.substring(0, half + 1) + ", " + str.substring(half + 1)
: str.substring(0, half) + ", " + str.substring(half));
System.out.print("Enter Y to continue or any input to exit: ");
} while (in.nextLine().toUpperCase().equals("Y"));
}
}
A sample run:
Tita, nic
Hello, World
Enter a string: Arvind
Arv, ind
Would you like to continue? [Y/N]: y
Enter a string: Kumar
Kum, ar
Would you like to continue? [Y/N]: Y
Enter a string: Avinash
Avin, ash
Would you like to continue? [Y/N]: n
Note:
% is a modulo operator.
Check String substring​(int beginIndex, int endIndex) and String substring​(int beginIndex) to learn more about substring functions of String.
Check https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html to learn about the ternary operator.
You could use String.substring() for this purpose:
String s = "Titanic";
int half = (s.length()+1)/2;
String part1 = s.substring(0, half);
String part2 = s.substring(half);
System.out.println(part1); // Prints: Tita
System.out.println(part2); // Prints: nic
Here (s.length()+1)/2 will auto-truncate 0.5 if it occurs because the division is between ints.

Empty String in an array of strings

I want to calculate the no of letters in words from 1 to 100. for example....
If the numbers 1 to 5 are written out in words: one, two, three, four, five,
then there are 3 + 3 + 5 + 4 + 4 = 19 letters used in total.
for which I have written the following code...
public static int helper(int a){
String ones[]= {"","one","two","three","four","five","six","seven","eight","nine","ten",
"eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen"
,"eighteen","nineteen"};
String tens[]= {"","","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
if(a<20){
return ones[a].length();
}
else
return tens[a/10].length();
}
public static int countLetters(int a){
if(a==100)
return 10;
else if(a<20){
return helper(a);
}
else{
return helper((a/10)*10)+ helper(a%10);
}
}
The main function looks like
public static void main(String[] args) {
// TODO Auto-generated method stub
int result=0;
for(int i=1;i<=100;i++){
result+=countLetters(i);
}
System.out.println(result);
}
The correct answer for this problem is 864. In the String ones[] array I used punctuation marks " " with space between them. The result returned was 872which is incorrect but after removing space between them answer returned was 864. I used "" without space. I wonder why this happened..?
Is there any logical aspect with respect to strings or string arrays for this problem ?
It only happens when you have the " " in the ones array.
If you have 20, you get the length of "twenty" + the length of helper(a%10) which is helper(0), which returns the length of " ". So you get the length of "twenty" + the length of " ".
This happens for 20, 30, 40, 50, 60 ,70 ,80 and 90. 8 times. That's why you see the 872.
The easiest fix is just making the first string "", like you did, but this would work too:
// return helper((a/10)*10)+ helper(a%10);
return helper((a/10)*10) + (a%10 == 0 ? 0 : helper(a%10));
A space in a String also adds to the length of a String for example:
"foo bar".length() --> 7
" foo bar ".length() -->9
"foobar".length() -->6
If you want to avoid having this problem and remove the outer space use trim.
"foo bar".trim().length() --> 7
" foo bar ".trim().length() -->7
"foobar".trim().length() -->6
Hope this helped.
What does this line of code calculate when value of a is 20?
return helper((a / 10) * 10) + helper(a % 10);
Your answer is in the calculation of this calculation. So, let's solve this out.
return helper((20 / 10) * 10) + helper(20 % 10);
which becomes:
return helper(20) + helper(0);
and in call against helper(0), your method executes this particular condition:
if(a<20){
return ones[a].length();
}
So, although you start your loop's iteration from 1 doesn't mean that index 0 for array ones is not being traversed.

What does this code really mean?

I made a static method array searcher for int for some pratise to clear myself for making algorithm. I made the static method:
public class ArraySearcher
public static int integerSearcher(int[] arr,int val){
int match = -1;
for(int i = 0; i < arr.length; i++){
if(arr[i]==val){
match = i;
break;
}
}
return match;
}
}
And in the main method I created an array of int and used my static method for finding a defined int in the new int array
int[] anIntArray = { 20, 30, 40, 60 };
int searchingAnArray = ArraySearcher.integerSearcher(anIntArray, 60);
if (searchingAnArray == -1){
System.out.println("match not found");
} else {
System.out.println("result found: "+ anIntArray[searchingAnArray]);
}
The question is that I did'n't understand the System.out.println("result found: "+ anIntArray[searchingAnArray]);" and what does this really means.
The question is that I did'n't understand the System.out.println("result found: "+ anIntArray[searchingAnArray]);" and what does this really means.
It means concatenate the String "result found: " with the int at position searchingAnArray in the array of int(s) anIntArray, then print that String followed by a newline.
You might iterate the array and print its contents like
for (int i = 0; i < anIntArray.length; i++) {
System.out.println("anIntArray[" + i + "] = " + anIntArray[i]);
}
The output (with your provided array) -
anIntArray[0] = 20
anIntArray[1] = 30
anIntArray[2] = 40
anIntArray[3] = 60
System.out.println("result found: "+ anIntArray[searchingAnArray]);
Will look for anIntArray on searchingAnArray position. I.e. will look for the value of the array anIntArray at position 3 (3 comes from your method), then it will print:
result found: 60
If you mean what does + means, is, as #HotLicks said on his comment, a concatenation. It will convert 60 into a String and add it to the same String as "result found: "
Another example:
String name = "Chuck Norris";
System.out.println("Hello " + name);
It will print
Hello you're not Chuck Norris
nah, just joking, it will print:
Hello Chuck Norris
Another example:
int year = 2014, day = 12, month = 8; //This could be done with a date type but for demonstration purposes I'll do it like this.
System.out.println("Today is: " + day + "/" + month + "/" + year);
And will print:
Today is: 12/8/2014
As you can see it will concatenate a String and then an int and so on, then print it.
It could be seen as:
String stringToBePrinted = "Today is: " + day + "/" + month + "/" + year;
System.out.println(stringToBePrinted);
If you call concatenation inside System.out.println(...) it will do something like the above (in an implicit way), something like "creating a local variable" and then print it. (Not exactly that way but you can see it like that to understand it).
Hopefully that is what you're looking for, the best explained as I could.

Tower of Hanoi error

Alright so I designed a code for the activity "The Towers of Hanoi". It is excellent for recursion exercise. The problem is that when I solve the puzzle via pencil and paper after outputting the results, it turns out to be wrong.
When n = 2, the puzzle works beautifully. But I just tried n = 3, and something is out of place.
My program is designed to make the 3 peg the final place for all the pieces. So the disks all finalize on peg 3.
public class TowersOfHanoi {
public static String hanoi(int nDisks, int fromPole, int toPole)
{
int helpPole;
String Pol1, Pol2, MyStep, MyPol; //contains moves
if(nDisks ==1)
{
return "There is " + nDisks + " disk moving from " + fromPole + "==>" + toPole + "\n";
}
else
{
helpPole = 6 - fromPole - toPole; //fromPole + helpPole + toPole = 6
Pol1 = hanoi(nDisks-1, fromPole, helpPole);
MyStep = "There are/is " + (nDisks-1) + " disk(s) moving from " + fromPole + "==>" + toPole + "\n";
Pol2 = hanoi(nDisks-1, helpPole, toPole);
MyPol = Pol1 + MyStep + Pol2; //+ = String concatenation
return MyPol;
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
int n = 3;
String StepsToSolution;
StepsToSolution = hanoi (n, 1, 3);
System.out.println(StepsToSolution);
}
}
Output:
There is 1 disk moving from 1==>3
There are/is 1 disk(s) moving from 1==>2
There is 1 disk moving from 3==>2
There are/is 2 disk(s) moving from 1==>3
There is 1 disk moving from 2==>1
There are/is 1 disk(s) moving from 2==>3
There is 1 disk moving from 1==>3
nDisks tells the method how many disks are to be moved. It is not an identification or the number of disks being moved at one particular time but the rest of the job in one particular place.
Thus. There will always be one disk moving from one peg to another, never 2. You do (nDisks-1) in myStep where you should have done 1. Or put more simply, myStep could have been: myStep = hanoi(1, fromPole, toPole);
Other than that your output of the moves are correct. That means you can increase to more disks and expect correct moves.

Stop and return value of a recursive method in java

I am trying to do a recursive method which returns a some random characters by some rules. The method works great, but the problem is that it doesn't return the value i need nor stop when i write return myString
here is the method(please take a look at comments):
public String RowGenerator(String sir) {
upper = "";
Log.v(TAG, "RowGenerator Started");
int randI = 1 + (int)(Math.random() * 4);
int randJ = 1 + (int)(Math.random() * 2);
int randK = 1 + (int)(Math.random() * 2);
Log.v(TAG, "inside RowGenerator: randI " + randI + ", randJ " + randJ + ", randK "+ randK);
String upper = sir.replaceAll("[^A-Z]+", "");
sir = sir.replaceAll("[^a-z]+", "");
Log.v(TAG, "String upper " + upper);
//checking if there is a..z & sir>=5
if ((sir.length()>=5) && upper.isEmpty()) {
Log.v(TAG, "sir <5 & !b " + String.valueOf(sir)); // here it prints out exactly what i need, but when i setText id has another value.
sir1.setText(String.valueOf(sir)); // this textview does not get the right value.
return sir; // i want to end the function here and return the value , as i call it as follows: someString = String.valueOf(RowGenerator(sir))
} else if (sir.isEmpty()) {
sir = S[1];
Log.v(TAG, "First sir value: " + sir);
RowGenerator(sir);
} else if (sir.length()<5 && upper.isEmpty()) {
sir = "";
RowGenerator(sir);
}
// if there is A..Z
else if (!upper.equals(null)) {
if(upper.equals(S[0])) {
sir = sir + S[1];
} else if (upper.equals(I[0])) {
sir = sir + I[randI];
} else if (upper.equals(J[0])) {
sir = sir + J[randJ];
} else if (upper.equals(K[0])) {
sir = sir + K[randK];
}
Log.v(TAG, "new value added to sir: " + sir);
RowGenerator(sir);
}
Log.v(TAG, "returning value "); // everything goes great till here, but then this log appears like 5-20 times randomly at each start, it should end in first if, but it got till here
sir1.setText(String.valueOf(sir));
return sir;
}
as far as i know return myString(); should stop the method and return the value, but it doesnt. please help me find what is wrong with my method.
any help would be very much appreciated.
When you call RowGenerator(sir); it does not return. It means the result is forgotten and the method processing continues.
As the final code block (containing the Log and return sir;) is not protected by an if it is executed every time, printing many logs. It also explains why the final result is incorrect (in these cases the method returns the value it received in parameter instead of recursing).
I guess you should replace RowGenerator(sir); by return RowGenerator(sir); to solve your issue.
Change RowGenerator(sir); statements to return RowGenerator(sir);.
Actually in recursive methods the return() action returns the value to the previous function call. For example if the method has called itself 4 times and in the 4th time return() is called then the method in the 3rd level will continue from the line in which the 4th function call was executed and so on until the first function does the return().
I don't know about your whole program but if this was all of your code a simple system.exit(1) would suffice.

Categories

Resources