Simple Recursion Explanation - java

Here is a recursive static method in Java.
public static int mystery(int m, int n) {
int result = 1;
if (m > 0) {
result = n * mystery(m-1, n);
}
System.out.println (m + " " + result);
return result;
}
What will be printed to the standard output if we make the method call mystery(3,4)? What would be the final return value from the call to mystery(3,4)?
What is the explanation to the answer for the standard output part.
Output:
0 1
1 4
2 16
3 64
The final return value is 64.

Consider n to be fixed (which for all intents and purposes it is) and let f(m) be mystery(m,n).
Then
f(0) = 1
f(1) = n * f(0) = n
f(2) = n * f(1) = n * n
f(3) = n * f(2) = n * n * n
Can you see the general pattern? Can you give a closed form for f(n)?

Given your code which is
public static int mystery(int m, int n) {
int result = 1;
if (m > 0) {
result = n * mystery(m-1, n);
}
System.out.println (m + " " + result);
return result;
}
Lets start with m = 3 and n = 4, lets try to emulate it by trying to be the debugger...
mystery(3,4){
int result = 1
if(3 > 0){
result = 4 * mystery(3-1,4);
//We proceed from this point only after evaluating mystery(2,4)
mystery(2,4){
int result = 1
if(2 > 0){
result = 4*mystery(2-1,4);
//Now we have to evaluate mystery(1,4)
mystery(1,4){
int result = 1;
if(1 > 0){
result = 4*mystery(1-1,4);
//Evaluate mystery(0,4)
mystery(0,4){
int result = 1;
if(0 > 0){
//Not evaluated
}
System.out.println(0 + " "+1);
return 1;
}...mystery(0,4) done continue with evaluation of mystery(1,4)
result = 4*1 //1 is what is returned by mystery(0,4)
System.out.println(1+ "" + 4);
return 4;
}//done with the evaluation of mystery(1,4), resume evaluation of mystery(2,4)
result = 4*4 //4 is the value returned by mystery(1,4)
System.out.println(2 + " " + 16);
return 16;
}//At this point we are done with evaluating (2,4) and on the way to resume evaluation of mystery(3,4)
result = 4 * 16
System.out.println(3 + " "+ 64)
return 64;
}
}
Hope this helps

This sample calculates m to the power n.
So in your case the value is 64.
However have you tried it out and did analysis on your part?

The first call is mystery(3,4) which then calls mystery(2,4) which then calls mystery(1,4) which then calls mystery(0,4). In this example, the base case is mystery(0,4), i.e. m > 0 evaluates to false and result = n*mystery(m-1,n) will not get executed (recursion terminates here). Your base case is on top of the call stack and the bottom of your stack is mystery(3,4). Evaluate from the top of the call stack towards the bottom…

Related

Turn recursive function into iterative version

i need to turn the following recursive code into an iterative version and my mind is fried. i feel like im missing something obvious. any help is appreciated.
public static int computeRecursive(int n){
if(n <= 1){
return n;
}
else{
return 2 * computeRecursive(n-2) + computeRecursive(n-1);
}
}
This is similar to an iterative fibonacci series, where you hold the initial two values of your function f() in two variables a and b. Then compute the result for the current N off of those previous two results:
public static int f(int n) {
if ( n <= 1 ) {
return n;
}
int result = 0;
int a = 0, // f(0) = 0
b = 1; // f(1) = 1
// start iteration at n=2 because we already have f(0) and f(1)
for(int i = 2; i <= n; i++) {
// f(n) = 2 * f(n-2) + f(n-1)
result = 2 * a + b;
// f(n-2) = f(n-1)
a = b;
// f(n-1) = f(n)
b = result;
}
return result;
}
In my opinion both recursive and iterative solutions are weak if you can just apply your maths skills and work out the formula.
In this case we have: f(n) = (2 ** n -(-1) ** n)/3. Bellow is how you work it out.
f(0) = 0
f(1) = 1
f(n) = f(n-1) + 2 * f(n-2)
So the polynomial for this recurrence is:
r ** 2 = r + 2
If you sole that you will get the values of r as r1 =−1 and r2 =2
So the solution to the recurrence is on the form:
f(n) = c1 ∗ r1 ** n + c2 ∗ r2 ** n
To work out the values for c1 and c2 constants just use the initial condition f(0) = 0 and f(1) = 1 and you will get
c1 = -1/3 and c2 = 1/3
So the final formula for your iteration is
f(n) = (-1 * (-1) ** n + 2 ** n)/3 = (2 ** n -(-1) ** n)/3.
Once you know the formula implementing it in java or any other language is easy.
public static int f(int n) {
return n <= 1 ? n: (Math.pow(2,n) - Math.pow(-1, n)) / 3;
}
Hope it helped
You can may be try the below code. It is similar to fibonacci series.
public static int computeRecursive(int n){
int a[]=new int[n];
a[0]=1; a[1]=1;
for(int i=2;i<n;i++){
a[i]=2*a[i-2]+a[i-1];
}
return a[n-1];
}

nth Binary palindrome with efficient time complexity

Given an integer N, i am trying to find the nth binary palindrome.I have written the following code but it is not efficient.is there a more efficient way in terms of time complexity.
I was trying it out as a problem online and i was supposed to output in 1 sec or less but for every input it takes 2 seconds.
public static Boolean Palind(String n){
String reverse = "";
int length = n.length();
for(int i = length - 1; i >=0;i--){
reverse = reverse + n.charAt(i);
}
if(n.equals(reverse)){
return true;
}
else{
return false;
}
}
public static int Magical(int n){
ArrayList<Integer> res = new ArrayList<Integer>();
for(int i = 1; i < Math.pow(2, n);i++){
if(Palind(Integer.toBinaryString(i))){
res.add(i);
}
}
return res.get(n-1);
}
The relevant OEIS entry (A006995) has a lot of nice tips if you read through it. For example, a(2^n-1)=2^(2n-2)-1 lets you skip right to the (2n - 1)th palindrome really quickly.
It also gives several implementations. For example, the Smalltalk implementation works like this (note that the input value, n, starts with 1 for the first palindrome, 0):
public static final int nthBooleanPalindrome(int n) {
if (n == 1) return 0;
if (n == 2) return 1;
int m = 31 - Integer.numberOfLeadingZeros(n);
int c = 1 << (m - 1);
int b;
if (n >= 3*c) {
int a = n - 3*c;
int d = 2*c*c;
b = d + 1;
int k2 = 1;
for (int i = 1; i < m; i++) {
k2 <<= 1;
b += a*k2/c%2*(k2 + d/k2);
}
}
else {
int a = n - 2*c;
int d = c*c;
b = d + 1 + (n%2*c);
int k2 = 1;
for (int i = 1; i < m - 1; i++) {
k2 <<= 1;
b += a*k2/c%2*(k2 + d/k2);
}
}
return b;
}
Try something like this maybe?
public static void main(String[] args) {
for (int i = 1; i < 65535; i++) {
System.out.println(
i + ": " + getBinaryPalindrom(i) + " = " + Integer.toBinaryString(getBinaryPalindrom(i)));
}
}
public static int getBinaryPalindrom(int N) {
if (N < 4) {
switch (N) {
case 1:
return 0;
case 2:
return 1;
case 3:
return 3;
}
throw new IndexOutOfBoundsException("You need to supply N >= 1");
}
// second highest to keep the right length (highest is always 1)
final int bitAfterHighest = (N >>> (Integer.SIZE - Integer.numberOfLeadingZeros(N) - 2)) & 1;
// now remove the second highest bit to get the left half of our palindrom
final int leftHalf = (((N >>> (Integer.SIZE - Integer.numberOfLeadingZeros(N) - 1)) & 1) << (Integer.SIZE -
Integer.numberOfLeadingZeros(N) - 2)) | ((N << (Integer.numberOfLeadingZeros(N) + 2)) >>> (Integer.numberOfLeadingZeros(N) + 2));
// right half is just the left reversed
final int rightHalf = Integer.reverse(leftHalf);
if (Integer.numberOfLeadingZeros(leftHalf) < Integer.SIZE / 2) {
throw new IndexOutOfBoundsException("To big to fit N=" + N + " into an int");
}
if (bitAfterHighest == 0) {
// First uneven-length palindromes
return (leftHalf << (Integer.SIZE - Integer.numberOfLeadingZeros(leftHalf)) - 1) | (rightHalf
>>> Integer.numberOfTrailingZeros(rightHalf));
} else {
// Then even-length palindromes
return (leftHalf << (Integer.SIZE - Integer.numberOfLeadingZeros(leftHalf))) | (rightHalf
>>> Integer.numberOfTrailingZeros(rightHalf));
}
}
The idea is that each number will become a palindrome once it reverse is added. To have the halves correctly aligned the halves just need to be shifted in place.
The problem why this has gotten a bit complex is that all uneven-length palindromes of a given leftHalf length come before all even-length palindromes of a given leftHalf length. Feel free to provide a better solution.
As int has 32 bit in Java there is a limit on N.
int-Version on ideone.com
And a BigInteger-version to support big values. It is not as fast as the int-version as the byte[]-arrays which store the value of the BigInteger create some overhead.
public static void main(String[] args) {
for (BigInteger i = BigInteger.valueOf(12345678); i.compareTo(BigInteger.valueOf(12345778)) < 0; i = i
.add(BigInteger
.ONE)) {
final BigInteger curr = getBinaryPalindrom(i);
System.out.println(i + ": " + curr + " = " + curr.toString(2));
}
}
public static BigInteger getBinaryPalindrom(BigInteger n) {
if (n.compareTo(BigInteger.ZERO) <= 0) {
throw new IndexOutOfBoundsException("You need to supply N >= 1");
} else if (n.equals(BigInteger.valueOf(1))) {
return BigInteger.valueOf(0);
} else if (n.equals(BigInteger.valueOf(2))) {
return BigInteger.valueOf(1);
} else if (n.equals(BigInteger.valueOf(3))) {
return BigInteger.valueOf(3);
}
final int bitLength = n.bitLength() - 1;
// second highest to keep the right length (highest is always 1)
final boolean bitAfterHighest = n.testBit(bitLength - 1);
// now remove the second highest bit to get the left half of our palindrom
final BigInteger leftHalf = n.clearBit(bitLength).setBit(bitLength - 1);
// right half is just the left reversed
final BigInteger rightHalf;
{
byte[] inArray = leftHalf.toByteArray();
byte[] outArray = new byte[inArray.length];
final int shiftOffset = Integer.SIZE - Byte.SIZE;
for (int i = 0; i < inArray.length; i++) {
outArray[inArray.length - 1 - i] = (byte) (Integer.reverse(inArray[i]) >>> shiftOffset);
}
rightHalf = new BigInteger(1, outArray).shiftRight(outArray.length * Byte.SIZE - bitLength);
}
if (!bitAfterHighest) {
// First uneven-length palindromes
return leftHalf.shiftLeft(bitLength - 1).or(rightHalf);
} else {
// Then even-length palindromes
return leftHalf.shiftLeft(bitLength).or(rightHalf);
}
}
I have the same idea with #Kiran Kumar: you should not count number one by one to find if it is a binary palindrome which is too slow, but rather find the internal pattern that number has.
List the number in binary string one by one, you can find the pattern:
0
1
11
101
1001
1111
...
1......1
And the following is some math problem:
We have 2^round_up((L-2)/2) palindrome of number with length L in binary format.
Sum up every shorter length number, we get following len to sum mapping:
for (int i = 1; i < mapping.length; i++) {
mapping[i] = (long) (mapping[i - 1] + Math.pow(2, Math.ceil((i - 1) * 1.0 / 2)));
}
If we find N range in [count(L), count(L+1)), we can concat it with remaining number:
public static long magical(long n) {
if (n == 0 || n == 1) {
return n;
}
long N = n - 2;
return Long.parseLong(concat(N), 2);
}
private static String concat(long N) {
int midLen = Arrays.binarySearch(indexRange, N);
if (midLen < 0) {
midLen = -midLen - 1;
}
long remaining = N - indexRange[midLen];
String mid = mirror(remaining, midLen);
return '1' + mid + '1';
}
private static String mirror(long n, int midLen) {
int halfLen = (int) Math.ceil(midLen * 1.0 / 2);
// produce fixed length binary string
final String half = Long.toBinaryString(n | (1 << halfLen)).substring(1);
if (midLen % 2 == 0) {
return half + new StringBuilder(half).reverse().toString();
} else {
return half + new StringBuilder(half).reverse().toString().substring(1);
}
}
Full code with test for produce large possible long can be found in my git repo.
Idea to optimize,
Let's look at the palindrome sequence 0, 1, 11, 101, 111, 1001 etc...
All numbers must begin and end with 1, So the middle bits only changes and midle substring should be palindrome for full string to become palindrome,
So let's take a 2 digit binary number - one palindrome is possible.
The binary of the decimal 3 is a palindrome. 11
For a 3 digit binary number 2 palindromes are possible, 2*(no of 1 digit palindrome)
The binary of the decimal 5 is a palindrome. 101
The binary of the decimal 7 is a palindrome. 111
For 5 digit binary number 4 palindromes are possible 2*(no of 3 digit palindrome)
10001,10101, 11011, 11111
and so on,
So it will be 2 + 20 + 21 + 22 +...... +2i-N ,
we solve for i and find out the palindrome number.
So by analysing this sequence we get an equation like 2(i/2)+1 -1 = N
where N is the No of palindrome,
and i is the number of bits in the nth palindrome string,
using this we can find the length of the String, from this we can find the string early.
This might be complex, but helps in solving higher values of N quickly....

Fraction to Recurring Decimal

Working on this problem, and also did a few reference to similar solutions. One thing I am confuse is, why we break the loop as long as there is one repetitive number? Is it possible the number repeat for 2-3 times and then changed to another different number? Thanks.
I mean this part specifically,
if (map.containsKey(num)) {
int index = map.get(num);
res.insert(index, "(");
res.append(")");
break;
}
The problem,
Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.
If the fractional part is repeating, enclose the repeating part in parentheses.
For example,
Given numerator = 1, denominator = 2, return "0.5".
Given numerator = 2, denominator = 1, return "2".
Given numerator = 2, denominator = 3, return "0.(6)".
public class Solution {
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0) {
return "0";
}
StringBuilder res = new StringBuilder();
// "+" or "-"
res.append(((numerator > 0) ^ (denominator > 0)) ? "-" : "");
long num = Math.abs((long)numerator);
long den = Math.abs((long)denominator);
// integral part
res.append(num / den);
num %= den;
if (num == 0) {
return res.toString();
}
// fractional part
res.append(".");
HashMap<Long, Integer> map = new HashMap<Long, Integer>();
map.put(num, res.length());
while (num != 0) {
num *= 10;
res.append(num / den);
num %= den;
if (map.containsKey(num)) {
int index = map.get(num);
res.insert(index, "(");
res.append(")");
break;
}
else {
map.put(num, res.length());
}
}
return res.toString();
}
}
thanks in advance,
Lin
The code doesn't stop when it sees a digit repeated. It stops when it notes that it has reached a state which it was already in. If it reaches the same state again, it means that we are about to repeat a division that we have already done, which means that the dividend and remainder are going to be the same, and we are going to do the same series of steps we have already done.
When that happens, it means a repetition, and it stops and adds the parentheses.
For example, let's divide 123 by 999. This should give us the repeating decimal 0.123123123..., so the output should be 0.(123).
123 / 999 is 0. The remainder is 123. We start with 0.
Multiply the remainder by 10. Now we have 1230 / 999. Dividend is 1, remainder is 231. Now we have 0.1
Multiply the remainder by 10. Now we have 2310 / 999. Dividend is 2, remainder is 312. Now we have 0.12
Multiply the remainder by 10. Now we have 3120 / 999. Dividend is 3, remainder is 123. Now we have 0.123
Multiply the remainder by 10. Now we have 1230 / 999... wait, we have already done that! That means that as we continue to divide, we'll get to that number again and again. Stop and put parentheses around the repeating part.
The map is there to tell us which numbers we have already divided, and at which index in the StringBuilder. When we find a number we have already divided, we use that index to know where to insert the parenthesis.
Clearly it's possible to have a decimal number with two or more decimals recurring and then a different decimal. For example 449/1000 = 0.449
Here is my solution in Java to this problem:
/**
* Given two integers a and b, return the result as a String.
* Display the repeating part of the fraction in parenthesis.
*
* Runs in O(b)
*
* #author Raed Shomali
*/
public class Divider {
private static final String DOT = ".";
private static final String ERROR = "ERROR";
private static final String LEFT_PARENTHESIS = "(";
private static final String RIGHT_PARENTHESIS = ")";
public static String divide(final int a, final int b){
if (b == 0) {
return ERROR;
}
int value = a / b;
int remainder = a % b;
return String.valueOf(value) + DOT + divider(remainder, b);
}
private static String divider(final int a, final int b) {
final Map<Integer, Integer> remainderIndexMap = new HashMap<>();
final List<Integer> values = new ArrayList<>();
int value;
int remainder = a;
while (!remainderIndexMap.containsKey(remainder)) {
remainderIndexMap.put(remainder, values.size());
remainder *= 10;
value = remainder / b;
remainder = remainder % b;
values.add(value);
}
final int index = remainderIndexMap.get(remainder);
final StringBuilder result = new StringBuilder();
for (int i = 0; i < index; i++) {
result.append(values.get(i));
}
result.append(LEFT_PARENTHESIS);
for (int i = index; i < values.size(); i++) {
result.append(values.get(i));
}
result.append(RIGHT_PARENTHESIS);
return result.toString();
}
}
Basically, the idea is simple. Using the same long division technique, you know when to stop when you have already seen the same remainder value.
Here are some test cases to show a few different scenarios:
divide(0, 0) // "ERROR"
divide(1, 2) // "0.5(0)"
divide(0, 3) // "0.(0)"
divide(10, 3) // "3.(3)"
divide(22, 7) // "3.(142857)"
divide(100, 145) // "0.(6896551724137931034482758620)"
If you are interested in a solution written in Go, you can find it here https://github.com/shomali11/util
This problem is actually very simple to solve if we use the long division technique that we learnt in 4th grade.
Suppose you need to divide 92 by 22. How do you do it using the long division method. How do you detect a repeating pattern?
Simple, you know you have a repeating pattern of decimals when you encounter a previously encountered reminder. You'll need to store the reminders and the corresponding index of the result in a dictionary and using the same you could detect/print repeating decimals. Working python code below.
def divide(numerator, denominator):
sign, res, lead = '', '', ''
if (numerator < 0) ^ (denominator < 0) and numerator != 0:
sign = '-'
numerator = abs(numerator)
denominator = abs(denominator)
remainders = defaultdict(list)
if numerator < denominator:
lead = '0'
_x = str(numerator)
r = 0
i = 0
j = 0
while True:
if i < len(_x):
d = int(str(r)+_x[i])
q = d // denominator
if not (q == 0 and len(res) == 0):
res += str(q)
r = d - (q * denominator)
i += 1
elif i >= len(_x) and j <= 9223372036854775807:
if r == 0:
return sign+lead+res
if j == 0:
remainders[r] = [True, len(res)+1]
res += '.'
d = int(str(r) + '0')
q = d // denominator
res += str(q)
r = d - (q * denominator)
if remainders[r] and remainders[r][0]:
res = res[0:remainders[r][1]] + '(' + res[remainders[r][1]:] + ')'
return sign+lead+res
remainders[r] = [True, len(res)]
j += 1
else:
return sign+lead+res

What is the logic of the recursion

Here is I have a factorial code using recursion.
class Factorial
{
public static void main(String args[])
{
Factorial f = new Factorial();
System.out.println(f.fact(Integer.parseInt(args[0])));
}
private int fact(int num)
{
int result;
if(num == 1)
return 1;
result = fact(num - 1) * num;
return result;
}
}
Now to run this program, I did this
D:\>java Factorial 3
Now according to the logic when it enters the fact function, where num = 3, so it will skip to
result = fact(num - 1) * num;
Here it will become
result = fact(3 - 1) * num;
i.e. result = fact(2) * num;
In this step, I am little confused Does it execute whole step i.e.
result = fact(num - 1) * num;
or just the fact(num - 1)
According to the logic, what it should do is call the fact function. So, the control of the program again reaches to the start of the fact function where num = 2. It will again skip to
result = fact(num - 1) * num;
So, it will become
result = fact(2 - 1) * num;
i.e. result = fact(1) * num;
Now again, it should call the fact function without executing the whole syntax & again reaches to the start of the fact method where num = 1. This time num == 1 will be matched & 1 will be returned. Now it will return to
result = fact(num - 1) * num;
So, it will become
result = fact(1 - 1) * num;
i.e. result = fact(0) * num;
Now what will happen next ?
Am I going right ? If not what will be the correction ?
I dont clearly understand the flow of this recursion program.
So, it will become
result = fact(1 - 1) * num;
Nope. For num = 2,
result = fact(num - 1) * num;
becomes
result = 1 * num; // i.e. 1 * 2
fact returns a value, which means the entire call has to be replace with that value.
Not sure why you would even think num changes at all. You have no num = ... in your code.
I added some trace into the program. Execute it and see the output. Should be easy to follow.
package snippet;
class Factorial {
public static void main(String args[]) {
Factorial f = new Factorial();
System.out.println(f.fact(Integer.parseInt("5")));
}
private int fact(int num) {
int result;
if (num == 1)
return 1;
result = fact(num - 1) * num;
System.out.println("fact(" + num + ") = " + result + " = fact(" + (num - 1) + ") * " + num);
return result;
}
}
fact(2) = 2 = fact(1) * 2
fact(3) = 6 = fact(2) * 3
fact(4) = 24 = fact(3) * 4
fact(5) = 120 = fact(4) * 5
120
Your logic is right but you have made 3 basic errors.
if we take your example;
First you run the program
D:\>java Factorial 3
then you have your first mistake because according to the logic all "num" have to be replaced by "3". So you get:
result = fact(3 - 1) * 3;
ie:
result = fact(2)*3;
then we have the second mistake because according to the definition of fact(num),
fact(2) = fact(2-1)*2
so we actually have
result = (fact(2-1)*2)*3
which is evaluated in
result = (fact(1)*2)*3
and here stand the third mistake because again according to fact(num) definition : fact(1) = 1 and not fact(1) = fact(1-1)*1
so we finally have:
result = ((1)*2)*3
To be more explicit if you follow all call sequence in the debugger you 'll have something like this( I put between brackets the value of the variable):
private int fact(num{3})
{
int result;
if(num{3}== 1)
return 1;
result = fact(num{3} - 1) * num{3};
private int fact(num{3-1})
{
int result;
if(num{3-1}== 1)
result = fact(num{3-1} - 1) * num{3-1};
private int fact(num{3-1-1})
{
int result;
if(num{3-1-1}== 1)
return 1;
}
return result{1*{3-1}};
}
return result{{1*{3-1}}*3};
}
Unless we hit the stop condition:
fact(num) = fact(num - 1) * num;
Therefore:
fact(3) = fact(3 - 1) * 3;
Keeping in mind that fact(1) = 1 (from the if statement early in the fact() method):
fact(3) = fact(2) * 3;
fact(2) = fact(1) * 2;
fact(1) = 1;
Replacing each element:
fact(3) = 1 * 2 * 3;
The recursion is used to repeatedly dive deeper into the process until a stop condition is encountered - in this case when num = 1.
The call f.fact(3) is expanding through the following steps:
1. result = fact(3 - 1) * 3 = fact(2) * 3
2. result = (fact(2 - 1) * 2) * 3 = (fact(1) * 2) * 3
3. result = 1 * 2 * 3 because fact(1) returns 1.
Your implementation is correct, But it will never reach fact(1-1) * 1 state ,as you return from method at if(num == 1).
num variable is limited to scope of method parameter. So for every call to fact method num variable is assigned a new value (i.e. num-1) and which is limited to that parameter scope only. So when fact(num-1) returns , value of num will be the original value and not the num-1.
The flow of your example is like this
step 1. fact(3)*3; //calling the function with num value 3
step 2. fact(2)*2; //calling fact() method again with num=2
step 3. fact(1)*1; //now num == 1 will be matched & 1 will be returned.
i. e.,
1 * 1 = 1; //now, steps 2 and 1 will be performed respectively
step 2. 1 * 2 = 2;
step 1. 2 * 3 = 6;
So, the final answer will be 6
Note: In step 3, the value is returned, so it will not again call this result = fact(0) * num; //which you have mentioned in question.

while nested in for loop. How does the decrement operator work?

I couldn't figure out how the decrement operator (e--)
works in code below, so i wrote the other class below it
to get the same result. I want to know how the decrement operator
achieves that result in the Power class. - Newbie.
int result, e;
for(int i=0; i < 10; i++) {
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
System.out.println("2 to the " + i +
" power is " + result);
}
Code written to achieve same result
int result = 1;
for(int i=0; i < 10; i++) {
if (i > 0) {
result*=2;
}
System.out.println("2 to the " + i +
" power is " + result);
}
So the first example is resetting result for each iteration of the main for loop, so it needs to recalculate from scratch each time, where as the second example is keeping the previous computed value. The if in the second example is not needed is it.
The decrement operator modifies the variable on which it's called. So e-- is effectively e = e - 1 (except the overall result of the expression is different, see below).
This code:
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
starts with result = 1 and then loops for i iterations doubling the value in result. Equivalent code using for which you seem more comfortable with:
result = 1;
for (e = 0; e < i; e++) {
result *= 2;
}
There are two forms of the decrement (and increment) operator: Prefix and postfix, depending on whether the operator is before (prefix) or after (postfix) its operand. Either could be used in the code you were asking about, because the only difference is the result of the expression.
Prefix: Suppose we have x = 5. The expression --x has the value 4: First we decrement x, then we take its new value as the result of the expression.
Postfix: Suppose we had x = 5 (again). The expression x-- has the value 5, with x ending up containing 4: First we grab the current value of x as the result of the expression, then we decrement it (because the -- is after x).
int x, r;
x = 5;
r = --x; // Prefix
System.out.println("r = " + r + ", x = " + x); // "r = 4, x = 4"
x = 5;
r = x--; // Postfix
System.out.println("r = " + r + ", x = " + x); // "r = 5, x = 4"
i figure out that by placing a System.out.println(e) i could "see" the variable "e" behavior in order to make sense of the decrement.
class Power {
public static void main(String args[]) {
int e;
int result;
for(int i=0; i < 10; i++) {
result =1 ;
e = i;
while(e > 0) {
System.out.println(e); // not part of the original program
result *= 2 ;
e--;
System.out.println(e); // not part of the original program
}
//System.out.println("2 to the " + i +
//" power is " + result);
}
This is the output:
C:\Users\enrique\Desktop\Hello.java>java Power: 1, 0, 2, 1, 1, 0, 3
e = 1(iteration 1), 2^1, e (1) decremented to 0, e = 2 (iteration 2), 2^2, e(2) decremented to 1, e = 1 re-enter The while but is ignored as 2^1 is already registered, e (1) decremented to 0, e = 3 (iteration 3), 2^3…

Categories

Resources