I am doing string (i.e. char array) processing with recursion. In my recursion tree, string located at child has length less than 1 w.r.t its parent and all children at the same height have same length of string but different characters. I want to stop the recursion whenever new string length is greater than or equal to old string length, but i am unable to insert this condition in between recursion. Using System.exit(0) terminates my complete program, which i don't want. Below is my code snippet-
private static void getMinLen(char[] oldStr) {
int len = oldStr.length;
/*
* This terminates the whole program, using break in place of
* System.exit(0) is not effective
*/
if (len < 2)
System.exit(0);
char[] newStr = new char[len - 1];
for (int i = 0; i < len - 1; i++) {
/*
* Every character is matched with its next character and a new char
* array is created having length (len-1)
*/
getMinLen(newStr);
}
}
Actually when i put System.out.println("length=" + len); in the 3rd line. First it prints the length in decreasing order but then length increases, decreases because of recursion. I mean the console shows the following-
length=6
length=5
length=4
length=3
length=2
length=1
length=3
length=3
length=2
length=1
length=4
length=3
length=2
length=1
I simply want to stop my recursion whenever new length becomes greater than or equal to old length.
In every call to getMinLen(oldStr) where the stop condition is not satisfied, you call getMinLen(newStr) several times (in fact as many times as there are elements in newStr). It is not clear from your question or your first comment whether this is intentional. (The fact that your newStr has as many elements as your loop has iterations may suggest it is not.)
If this is not intentional, just move the recursive call one line down, i.e. behind the closing } of the loop.
If it is intentional, the problem may be that you have not understood how recursion works. The fact that the stop condition is fulfilled somewhere is not recorded globally and only relevant for the single call in which the stop condition is fulfilled. This point was itself reached by a recursive call getMinLen's for loop (unless you start with a very short string), and that (outer) for loop continues to execute all subsequent calls to getMinLen--why should it stop? To make it stop, a global boolean variable would help, but be very inelegant. Alternatively, you could make the function return a boolean value and check before each recursive call whether a previous one returned true. You may also, however, reconsider whether a recursive approach is really the most suitable for the problem.
Just replace System.exit(0); by return; at the line you want to exit your method
You should use return.
if (len < 2)
return;
Note that break does only "break" loops or switch statements. To leave a method you have to reach the return statement or end of the method (which acts as an implicit return statement in case the return type is void).
Note that your method does the following:
Assume the initial length is 4:
1. create a new array of length 3 (4-1)
2. call the method recursively 3 times with an array of length 3
3. each new call creates an array of length 2 (3-1)
4. call the method recursively again, now 2 times and with an array of length 2
5. each new call creates an array of length 1 (2-1)
6. call the method recursively again, now once and with an array of length 1
7. each new call creates an array of length 0 (1-1)
8. those methods won't enter the loop since the condition now is `i < 0`, which is false with `i = 0`
Thus, when printing each length, I'd expect the following output
4 //initial call
3 //first iteration of step 2
2 //first iteration of step 4
1 //only iteration of step 6
2 //second iteration of step 4
1
3 //second iteration of step 2
2
1
2
1
3 //third iteration of step 2
2
1
2
1
If you just want one iteration and then stop, why did you put the loop in there?
Related
I'm having trouble understanding how the code is able to recover the remaining integers after they are taken off the original value via x/10. Is there something going on behind the scenes?
// precondition: x >= 0
// Question: What is printed from method call mystery(123456)?
public void mystery(int x) {
if ((x/10) != 0) {
mystery(x/10);
}
System.out.print(x % 10);
}
Each invocation of mystery creates a new stack frame in the JVM. These frames are used to store parameters, local variables, and other data which I'll omit for brevity. In your recursive step (mystery(x / 10)), each newly created stack frame will be holding a successively smaller copy of the result of x / 10. Once the base case is reached, each stack frame will then print the value of its copy of x % 10.
So, for example, mystery(123456):
Frame 1: 123456
Frame 2: 12345
Frame 3: 1234
Frame 4: 123
Frame 5: 12
Frame 6: 1 (Base case is reached! Each frame will now print and return)
Modulo 10 will always print the rightmost digit. So that means after all the frames are finished, you will be left with 123456. If you are expecting 1, then how might you go about modifying your solution? (Hint: think about base cases!)
Each recursive call to mystery() happens before the final print statement that prints the digit. The current state of the program is saved to the stack before the function begins to execute again, so on the last execution of the function, when x/10 = 0, the 1 is printed. Then the program returns to the previous execution of the function, where x = 12, and continues to that print statement to print 12 % 10 = 2. This continues the same way until the program reaches the top level execution of the function.
This page explains recursion and has a useful diagram for the factorial example that shows how functions are called and returned.
I am trying to do in Java:
int i=5;
while(i-- >0) {
System.out.println(i);
}
When running this program the output is:
4
3
2
1
0
I am very surprised to see 0 in output. I am new in development. Can anyone justify this?
In your while condition i-- > 0, the variable i is evaluated first and then decremented.
When i reaches the value 1, it will pass the loop test and then get decremented to 0. This is why the print statement shows 0 in the output.
Here is a mnemonic you can use to keep track of how the decrement and increment operators work:
int i = 5;
System.out.println("When i = 5 then:");
System.out.println("i-- is " + i--);
i = 5;
System.out.println("--i is " + --i);
Output:
When i = 5 then:
i-- is 5
--i is 4
Simply, because you compare i>0 and decrement i afterwards.
// If I is 1, you compare 1>0 and decrement i afterwards.
// This is how the postdecrement operator works
while(i-- >0) {
System.out.println(i);
}
the loop will behave like the following.
is i=5 > 0?
decrement i to 4
output i = 4.
is i=4 > 0?
decrement i to 3
output i = 3.
...
and so on
As you can see the value you compare to 0 is allways higher then the one you are outputing. This happens due to how the -- operator works. If it´s preceding to the i as --i it will decrement the variable i first and return it´s value afterwards. If it´s not preceding as in your case i-- you will have the value of i returned first and i beeing decremented afterwards.
Postdecrement/Increment operator works on the principle "Use first and then Change"
Initially value of i=5, when it enters while loop it will compare value of i first and then it prints the decremented value. Here i will show you each iteration along with checks performed in each iteration,
Now value of i=5(in memory), inside while(5>0), it prints 4.
Now value of i=4(in memory), inside while(4>0), it prints 3.
Now value of i=3(in memory), inside while(3>0), it prints 2.
Now value of i=2(in memory), inside while(2>0), it prints 1.
Now value of i=1(in memory), inside while(1>0), it prints 0.
Hope now you are clear to go ahead. Gud Luck.
The post-decrement operator -- is like a post-paid service. Like a credit card, first you use, then you pay.
I thought I can give you a real-life idea of what really is occurring in this statement, when i == 1
while(i-- >0)
So, first you check if i(1)>0. 1>0 So, yes it is. Right after this statement is done, i becomes 0. Then, you print that value.
Alternatively, you might also get this intuition by noticing that although your loop started with i=5, the value 5 never got printed.
Since you are using the post-decrement operator in the while loop, when i is 1, i-- returns 1, and then inside the loop you get 0 when you print i for the last time.
Only because of post decrement operator (i--) will check the condition first then decrease the value of i. Output is giving such. Thank you
int i=5; //initialize with 5
while(i-- >0) { //post decrements operator so, check condition first then decrease the value.
System.out.println(i);
}
In first iteration of while loop will check 5 > 0 will be checked after that decrease the value of i and i will become 4 So, Print it 4 not 5.
When i = 5 conditional statement will be (5>0) (true) and print 4.
i = 4 conditional statement will be (4>0) (true) and print 3.
i = 3 conditional statement will be (3>0) (true) and print 2.
i = 2 conditional statement will be (2>0) (true) and print 1.
i = 1 conditional statement will be (1>0) (true) and print 0.
Now, i became 0 so conditional statement will be (0>0) (False).
So, loop exits.
To get desired output try this
while(--i >0) {
System.out.println(i);
}
I know the rationale behind nested loops, but this one just make me confused about the reason it wants to reveal:
public static LinkedList LinkedSort(LinkedList list)
{
for(int k = 1; k < list.size(); k++)
for(int i = 0; i < list.size() - k; i++)
{
if(((Birth)list.get(i)).compareTo(((Birth)list.get(i + 1)))>0)
{
Birth birth = (Birth)list.get(i);
list.set( i, (Birth)list.get( i + 1));
list.set(i + 1, birth);
}
}
return list;
}
Why if i is bigger then i + 1, then swap i and i + 1? I know for this coding, i + 1 equals to k, but then from my view, it is impossible for i greater then k, am i right? And what the run result will be looking like? I'm quite confused what this coding wants to tell me, hope you guys can help me clarify my doubts, thank you.
This method implements a bubble sort. It reorders the elements in the list in ascending order. The exact data to be ordered by is not revealed in this code, the actual comparison is done in Birth#compare.
Lets have a look at the inner loop first. It does the actual sorting. The inner loop iterates over the list, and compares the element at position 0 to the element at position 1, then the element at position 1 to the element at position 2 etc. Each time, if the lower element is larger than the higher one, they are swapped.
After the first full run of the inner loop the largest value in the list now sits at the end of the list, since it was always larger than the the value it was compared to, and was always swapped. (try it with some numbers on paper to see what happens)
The inner loop now has to run again. It can ignore the last element, since we already know it contains the largest value. After the second run the second largest value is sitting the the second-to-last position.
This has to be repeated until the whole list is sorted.
This is what the outer loop is doing. It runs the inner loop for the exact number of times to make sure the list is sorted. It also gives the inner loop the last position it has to compare to ignore the part already sorted. This is just an optimization, the inner loop could just ignore k like this:
for(int i = 0; i < list.size() - 1; i++)
This would give the same result, but would take longer since the inner loop would needlessly compare the already sorted values at the end of the list every time.
Example: you have a list of numbers which you want to sort ascendingly:
4 2 3 1
The first iteration do these swap operations: swap(4, 2), swap(4, 3), swap(4, 1). The intermediate result after the 1st iteration is 2 3 1 4. In other words, we were able to determine which number is the greatest one and we don't need to iterate over the last item of the intermediate result.
In the second iteration, we determine the 2nd greatest number with operations: swap(3, 1). The intermediate result looks then 2 1 3 4.
And the end of the 3rd iteration, we have a sorted list.
I'm having trouble understanding what happens to this piece of code when it returns. After it outputs 10 9 8 7 6 5 4 3 2 1 0 why does it outputs 1 after 0 and not 0 again?
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
a(b+1);
}
Well you have a(b+1) that means there is no end condition for this case which means StackOverflow. as pointed out in the comment, it is stuck between 0 and 1
If b is less than 0, the execution of the method stops. The Code below the return statement will not be executed.
While this particular example returns a StackOverflowError I don't think that's the kind of answer you're looking for. So pretending that error-causing line wasn't there let me demonstrate what is happening:
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
a(b+1); //assuming this didn't go to infinity
}
The method runs exactly like it reads, but you create sub-tasks.
It checks the if statement, then prints the value of b. Then it runs a(b-1) and then runs a(b+1).
You're getting odd results because then it runs a(b-1) is actually a series of tasks in and of itself. THAT method does all the things I mentioned before and they will all happen BEFORE the first instance ever reaches a(b+1).
Lets say you called a(1);
1 is not less than 0
print 1
a(1-1) //which is zero a(0)
//begin sub-task a(0)
0 is not less than 0
print 0
a(0-1) // which is -1
//begin sub-task a(-1)
-1 is less than 0 so return
a(0+1)
1 is not less than zero
print 1
a(1-1) // which is zero
zero is not less than zero
print zero
a(0-1)
etc. etc.
It may be easier to think of this as
public static void a(int b){
if(b<0)
return;
System.out.println(b);
a(b-1);
System.out.println(b + " is done");
}
This does the following with a(1);:
if(1 < 0) // false
print 1
begin a(1-1) or a(0)
if(0 < 0) // false
print 0
begin a(0-1) or a(-1)
if(-1 < 0) //true so return IE go back to the calling method
print "0 is done"
print "1 is done"
A stack overflow. The call to a(b+1) every time means there will never be a point where the original function can return, or the call to a(b+1), or the call to a(b+1+1) and so on.
The return in this case just finishes the current function/method call, popping things out of the stack and going back up to the previous method call. In other words, that's just your (incomplete) base case. Unless you add a termination condition for the case where b increases, the current base case won't be enough to say stop all recursion and you'll get a SO exception.
The following is the inside of a method for collision detection while inserting into my own hash table. I'm working with small test numbers and trying to get my logic right, the variable hash is set to 0 and the table.length is 10.
else
{
//problem here
int initial=(hash-1)%table.length;
while (table[hash]!=null)
{
hash+=1;
System.out.println(initial);
if (hash==table.length)
{
hash=0;
}
if (hash==initial)
{
System.out.println("FULL!");
break;
}
The variable initial needs to be the index BEFORE whatever my current one is (hash). My problem is if hash is 0, initial needs to be set to 9. I thought this would work but I'm getting -1 when hash is set to 0 for example. The first IF statement loops back to the first index if you for example started in the middle at 5 or something, the second one is for for when you've checked all indexes and they're all full.
Since you use %, there is no risk of overflow, so you can just change the line to
int initial = (hash - 1 + table.length) % table.length;
to get around this problem.