Resolving a stack with 2 recursive calls - java

I'm trying to refresh my skills in recursion and so far everything has gone well. However, I have never seen a problem where a string is the value of two recursive calls. Does the first recursive call ignore the rest of the statement? Is the 2nd recursive call still taken into account when it is resolved? I tried tracing it under the assumption that like a return statement, the first recursive call would break the loop. Therefore, I was under the impression that the rest of the code in the if statement would not be taken into account.
public class Example {
public static String encrypt(String word) {
int pos = word.length() / 2;
if (pos >= 1)
word = encrypt(word.substring(pos)) + encrypt(word.substring(0,pos));
return word;
}
public static void main(String []args){
System.out.println(encrypt("SECRET"));
}
}
While my expected output was "TETRET", the actual output was supposed to be "TERCES." Anyone mind explaining where my tracing or logic went wrong?

I tried tracing it under the assumption that like a return statement, the first recursive call would break the loop.
This is incorrect. Both will be evaluated.
word = encrypt(word.substring(pos)) + encrypt(word.substring(0,pos));
The first recursive call will get pushed onto the stack, and the second will be saved on the stack to be evaluated once the first call has been returned to the call stack. Here's a visual representation:
1
/ \
2 5
/ \
3 4
This is assuming 3, 4, and 5 reach the base case and thus do not continue the recursion

The word is returned in reverse order. I am unsure what you were trying to do instead. Here is a partial trace of your code, using "ABCDEF" instead of "SECRET", showing how it works :
+=================================+====================+===========================================+==============+==========================================+==============+
| word (initial call) | pos (initial call) | word (call 2) | pos (call 2) | word (call 3) | pos (call 3) |
+=================================+====================+===========================================+==============+==========================================+==============+
| "ABCDEF" | 3 | | | | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| encrypt("DEF") + encrypt("ABC") | | "DEF" | 1 | | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | encrypt("EF") + encrypt ("D") | | "EF" | 1 |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | | | encrypt("F") + encrypt("E") | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | | | (call 4 returns "F", call 5 returns "E") | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | | | "FE" | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | (call 3 returns "FE", call 6 returns "D") | | | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
| | | "FED" | | | |
+---------------------------------+--------------------+-------------------------------------------+--------------+------------------------------------------+--------------+
Here is the order in which the calls are made and "resolved" (by resolved, I mean that the return statement of the function is executed) :
encrypt("ABCDEF")
encrypt("DEF")
encrypt("EF")
encrypt("F")
resolution of encrypt("F") // returns "F"
encrypt("E")
resolution of encrypt("E") // returns "E"
resolution of encrypt("EF") // returns "FE"
encrypt("D")
resolution of encrypt("D") // returns "D"
resolution of encrypt("DEF") // returns "FED"
encrypt("ABC")
(...)
Of course the same logic applies to encrypt "ABC" as it did to encrypt "DEF", so if you understand this part you should understand the rest.

If you place the print statement as I have shown, you can see how the returned word and pos are altered. Then just backtracking off the stack, the word is reconstructed in reverse order.
public class Example {
public static String encrypt(String word) {
int pos = word.length() / 2;
System.out.println(word + " " + pos);
if (pos >= 1) {
word = encrypt(word.substring(pos)) + encrypt(word.substring(0, pos));
}
return word;
}
public static void main(String[] args) {
System.out.println(encrypt("SECRET"));
}
}
Produces the following output:
SECRET 3
RET 1
ET 1
T 0
E 0
R 0
SEC 1
EC 1
C 0
E 0
S 0
TERCES

Related

why my up function changes input out of its block in Java

i wrote a function to change an input matrix and return the changed matrix in java.
but when i want use input matrix after calling this function, i see that my input matrix has been changed.
My Up Function:
char[][] up(char[][] state, int[] empty){
int ie = empty[0];
int je = empty[1];
if(tools.checkMoves(state,1,ie,je)){
state[ie][je] = state[ie-1][je];
state[ie-1][je] = '0';
}else{
System.out.println("Move not allowed");
}
return state;
}
print matrix then call function and again print matrix
System.out.println(gameGenerator.printGame(nextState));
System.out.println(gameGenerator.printGame(moves.up(nextState,tools.getEmpty(nextState))));
System.out.println(gameGenerator.printGame(nextState));
Answer is:
1.print input matrix
-------------
| 1 | 2 | 3 |
| 5 | 7 | 6 |
| 4 | | 8 |
-------------
2.print matrix returned from function
-------------
| 1 | 2 | 3 |
| 5 | | 6 |
| 4 | 7 | 8 |
-------------
3.print input matrix after calling up function and it's CHANGED!
-------------
| 1 | 2 | 3 |
| 5 | | 6 |
| 4 | 7 | 8 |
-------------
please help ! Thanks all
You are modifying your input matrix in those two lines:
state[ie][je] = state[ie-1][je];
state[ie-1][je] = '0';
Java is an object-oriented language. When you pass an object to a method, you pass its reference. The reference is copied but not the object itself. When you modify the object inside the method, it is still modified after the method (which is normal since it is the same object).
If you don't want your method to create any side effect, you have create a copy of the matrix at the beginning of your method and modify the copy.
Additional note:
You may wonder why when the input is a primitive type, then the value is still the same outside the method, like this:
public void modify(int i){
i = 5;
}
That's because Java is pass by value, which means that the value of i is copied when the method is called, so only the copy is modified. As I wrote above, objects references are also passed by value, which means that the reference is copied. (to explain it roughly, you copy the value of the pointer to the object).
If you'd like a more detailed explanation, you can read this : http://www.javadude.com/articles/passbyvalue.htm

Can someone explain the flow of control of this program?

This is an example program in my AP Computer Science course, and I can't understand the flow of control of it.
public static void mystery( int n )
{
System.out.println( "mystery called with n = " + n );
if ( n == 0 )
{
System.out.println( "n is zero so no more recursive calls!" );
return;
}
mystery( n - 1 );
System.out.println( "We did it again with n = " + n );
}
public static void main( String[] args )
{
mystery( 5 );
}
It outputs this:
mystery called with n = 5
mystery called with n = 4
mystery called with n = 3
mystery called with n = 2
mystery called with n = 1
mystery called with n = 0
n is zero so no more recursive calls!
We did it again with n = 1
We did it again with n = 2
We did it again with n = 3
We did it again with n = 4
We did it again with n = 5
So far, I understand the recursive method and how it recalls itself via:
mystery( n - 1 );
However, I don't see how it can output those five statements after:
n is zero so no more recursive calls!
Logically, it seems like it would only state:
We did it again with n = 0
Can anyone help a student out and explain to me how it output what it did?
When a function finishes, the function that called it has the opportunity to complete and execute more code.
Here is an illustration of how this recursion happens.
Each level of recursion is indicated by an increase in indentation.
mystery(5):
"mystery called with n = 5"
mystery(4):
"mystery called with n = 4"
mystery(3):
"mystery called with n = 3"
mystery(2):
"mystery called with n = 2"
mystery(1):
"mystery called with n = 1"
mystery(0):
"mystery called with n = 0"
"n is zero so no more recursive calls!"
mystery(0) returns
"We did it again with n = 1"
end of mystery(1)
"We did it again with n = 2"
end of mystery(2)
"We did it again with n = 3"
end of mystery(3)
"We did it again with n = 4"
end of mystery(4)
"We did it again with n = 5"
end of mystery(5)
After 'n is zero so no more recursive calls!' the method continues (the state is put on the stack and then loaded after the call to method(n-1) finishes.
Here is a good way of thinking about recursive programs: when you read program's code, pretend that you know what the program does, even though you don't know it yet. In your situation, this would look like this:
If n == 0, print fixed message - that's the no more recursive calls! string
If n != 0, print n followed by printing whatever the program prints for n-1, followed by printing n again - in other words, there's a "frame" of two messages around whatever the program prints for n-1
Here is how this would look:
mystery called with n = <something>
... whatever the program prints in between...
We did it again with n = <something>
The first printout happens before entering the recursive part of the call; the last printout happens after returning from the recursive part. Note that <something> is the same at the top and at the bottom, because the value of n is stored on each stack frame, and gets set to the previous value as the recursion unwinds.
With this picture in place, it is easy to see that you keep adding nested "frames" until you hit n==0, at which point you print the message in the middle.
The first five times through the mystery method, the method does not stop at the recursive call. It continues on, to output "we did it again." But I suppose since mystery is blocking, the method is only allowed to finish up once the last recursive call is returned. So upon hitting n = 0 the first five calls continue on to their original conclusion, printing "We did it again with n = ..."
Here's a run through of what this recursive method does:
mystery(5): {
| println( "mystery called with n = 5" );
|
| n != 0:
| skip return
|
| mystery(n - 1) is mystery(4)
|
| call mystery(4): {
| | println( "mystery called with n = 4" );
| |
| | n != 0:
| | skip return
| |
| | mystery(n - 1) is mystery(3)
| |
| | call mystery(3): {
| | | println( "mystery called with n = 3" );
| | |
| | | n != 0:
| | | skip return
| | |
| | | mystery(n - 1) is mystery(2);
| | |
| | | call mystery(2): {
| | | | println( "mystery called with n = 2" );
| | | |
| | | | n != 0:
| | | | skip return
| | | |
| | | | mystery(n - 1) is mystery(1);
| | | |
| | | | call mystery(1): {
| | | | | println( "mystery called with n = 1" );
| | | | |
| | | | | n != 0:
| | | | | skip return
| | | | |
| | | | | mystery(n - 1) is mystery(0);
| | | | |
| | | | | call mystery(0): {
| | | | | | println( "mystery called with n = 0" );
| | | | | |
| | | | | | n == 0:
| | | | | | return from mystery(0)
| | | | | }
| | | | |
| | | | | back inside mystery(1), continue executing where we left off
| | | | | println("We did it again with n = 1")
| | | | | method ends; return to caller
| | | | }
| | | |
| | | | back inside mystery(2), continue executing where we left off
| | | | println("We did it again with n = 2")
| | | | method ends; return to caller
| | | }
| | |
| | | back inside mystery(3), continue executing where we left off
| | | println("We did it again with n = 3")
| | | method ends; return to caller
| | }
| |
| | back inside mystery(4), continue executing where we left off
| | println("We did it again with n = 4")
| | method ends; return to caller
| }
|
| back inside mystery(5), continue executing where we left off
| println("We did it again with n = 5")
| method ends; program ends
}

What's wrong with this recursion for checkers move generation?

I'm writing a simple checkers game in Java. The hard part so far is to generate a list of possible jumps for a piece, especially when there are several paths to jump. I have this recursion to find all possible paths to do a series of jumps. Here's some code:
/*
* possibleJumps(Square pos, Board b, Move jump, ArrayList<Move> moves)
* Add all possible jumps from the position b on board b to movelist moves.
*/
void possibleJumps(Square pos, Board b, Move jump, ArrayList<Move> moves) {
ArrayList<Move> simpleJ = this.simpleJumps(pos, b);
//jump.addJumpSquare(pos);
//System.out.println("check jump " + pos + " so far:" + jump);
if (simpleJ.isEmpty()) {
// no more jumps -> end this jump and add it to the list
jump.endJump(pos);
moves.add(jump);
System.out.println("found jump" + jump);
return;
}
for(Move j:simpleJ) {
jump.addJumpSquare(j.jumped.get(0)); // add the jumped square to the jump path
possibleJumps(j.to, b.doMove(j), new Move(jump), moves);
}
}
Just to explain: simpleJumps generates a list of possible jumps over one square (so basically all attack moves). That works fine.
Here's the test board:
A B C D E F G H
---------------------------------
1 | | o | | | | | | | 1 (0)
---------------------------------
2 | | | | | | | | | 2 (1)
---------------------------------
3 | | o | | o | | o | | o | 3 (2)
---------------------------------
4 | | | | | | | | | 4 (3)
---------------------------------
5 | | o | | o | | o | | o | 5 (4)
---------------------------------
6 | | | | | | | | | 6 (5)
---------------------------------
7 | | o | | O | | o | | | 7 (6)
---------------------------------
8 | x | | | | | | | | 8 (7)
---------------------------------
Here's the output I get:
found jumpa8c2 via b7-b5-b3-
found jumpa8c2 via b7-b5-d5-d3-
found jumpa8g2 via b7-b5-d5-d3-f3-
What it should be is:
found jumpa8c2 via b7-b5-b3-
found jumpa8c2 via b7-d5-d3-
found jumpa8g2 via b7-d5-f3-
This is, in principle, very similar to:
Print all paths from root to leaf in a Binary tree
which I read and used to get as far as I have gotten, but I'm missing something probably very simple...
Any ideas?
In this loop
for(Move j:simpleJ) {
jump.addJumpSquare(j.jumped.get(0)); // add the jumped square to the jump path
possibleJumps(j.to, b.doMove(j), new Move(jump), moves);
}
you are reusing the same jump for all possible moves - if you got 3 possible moves x,y,z you will end up with x, y and z added to the jump path.
So you either have to
create a new jump-object (with appropriate state) at each iteration or
remove the added square at the end of the iteration

What does the pipe character do in a Java method call?

I've seen the pipe character used in method calls in Java programs.
For example:
public class Testing1 {
public int print(int i1, int i2){
return i1 + i2;
}
public static void main(String[] args){
Testing1 t1 = new Testing1();
int t3 = t1.print(4, 3 | 2);
System.out.println(t3);
}
}
When I run this, I simply get 7.
Can someone explain what the pipe does in the method call and how to use it properly?
The pipe in 3 | 2 is the bitwise inclusive OR operator, which returns 3 in your case (11 | 10 == 11 in binary).
it's a bitwise OR.
The bitwise representation of numbers is like this:
|2^2|2^1|2^0|
| 4 | 2 | 1 |
the bitwise representation of 3 is:
|2^2|2^1|2^0|
| 4 | 2 | 1 |
| - | X | X | => 3
the bitwise representation of 2 is:
|2^2|2^1|2^0|
| 4 | 2 | 1 |
| - | X | - | => 2
The bitwise OR will return 3 because when using OR at least one bit must be "occupied". Since the first and second bit are occupied (3 | 2) will return 3.
Finally, the addition 4 + 3 = 7.
The | operator performs a bitwise OR on the operands:
3 | 2 ---> 0011 (3 in binary)
OR 0010 (2 in binary)
---------
0011 (3 in binary)
Here's the pattern:
0 OR 0: 0
0 OR 1: 1
1 OR 0: 1
1 OR 1: 1
Using |:
if(someCondition | anotherCondition)
{
/* this will execute as long as at least one
condition is true */
}
Note that this is similar to the short-circuit OR (||) commonly used in if statements:
if(someCondition || anotherCondition)
{
/* this will also execute as long as at least one
condition is true */
}
(except that || does not enforce the need to continue checking other conditions once a true expression has been found.)

How to print a 2D array with varying sized cells?

I have a 2-D array where each cell is a Set.
In each set is a different size, say for example, ranging from 0 to 5.
I want to print out the 2-D array in a format such that it's easily readable.
Example
HashSet<String>[][] schedule = (HashSet<String>[][]) new HashSet[3][5];
schedule[0][0].add("A");
schedule[0][0].add("B");
schedule[0][0].add("C");
schedule[0][2].add("D");
schedule[0][2].add("E");
schedule[1][0].add("F");
schedule[1][1].add("G");
schedule.print();
will produce
-----------------
| A | | D | | |
| B | | E | | |
| C | | | | |
-----------------
| F | G | | | |
-----------------
| | | | | |
-----------------
obviously without the '-' and '|', but you get the point.
The only viable solution I can think of is creating and remembering the iterator for each column (so remembering 5 iterators at the same time) and iterating through each column, outputting one element at a time until there are no more elements in any of the iterators.
One problem is that in the case of G, it expands the second column even though there are not any values in the first row, second column. I can get around this by buffering each column with tabs.
Obviously this hack does not scale with additional columns, so I was wondering if there were any cute tricks that I might have forgotten.
Thanks!
With a few modifications to the code (you forgot to instantiate the positions in the array!), you can definitely print out the jagged sets.
Hint: Make use of the iterator() method that's provided with the HashSet. An iterator moves over a collection of objects, returning one at a time, then pausing until it's invoked again, or there's nothing left to iterate over. You can find more information about iterators in general at Wikipedia's Iterator article.
Using this, you can gather up the results in each HashSet inside of a String (in any way you desire), and print them out at the end.
Code Snippet:
Iterator first = schedule[0][0].iterator();
Iterator second = schedule[0][2].iterator();
// And so forth
String firstResult = "";
String secondResult = "";
// And so forth
while (first.hasNext()) {
firstResult += first.next() + "\t";
if (!first.hasNext()) {
firstResult += "\n";
}
}
while (second.hasNext()) {
secondResult += second.next() + "\t";
if (!second.hasNext()) {
secondResult += "\n";
}
}
// And so forth
System.out.print(firstResult + secondResult + someResult + anotherResult);
Filling in the blanks is an exercise for the reader.
With this, the result is as follows:
A B C
D E
F
G

Categories