I just wanted to create a little Java-Puzzle, but I puzzled myself. One part of the puzzle is:
What does the following piece of code do:
public class test {
public static void main(String[] args) {
int i = 1;
i += ++i + i++ + ++i;
System.out.println("i = " + i);
}
}
It outputs 9.
My (at least partly) wrong explanation:
I'm not quite sure, but I think the term after i += gets evaluated like this:
So
int i = 1;
i += ++i + i++ + ++i;
is the same as
int i = 1;
i += ((++i) + (i++)) + (++i);
This gets evaluated from left to right (See Pre and postincrement java evaluation).
The first ++i increments i to 2 and returns 2. So you have:
i = 2;
i += (2 + (i++)) + (++i);
The i++ returns 2, as it is the new value of i, and increments i to 3:
i = 3;
i += (2 + 2) + ++i;
The second ++i increments i to 4 and returns 4:
i = 4;
i += (2 + 2) + 4;
So you end up with 12, not 9.
Where is the error in my explanation? What would be a correct explanation?
i += ++i + i++ + ++i; is the same as i = i + ++i + i++ + ++i;
The right-hand side is calculated from left-to-right, yielding i = 1 + 2 + 2 + 4; (which yields i = 9).
The output is 9 (try it)
int i = 1;
i += ++i + i++ + ++i;
becomes
i = 1 + 2 + 2 + 4
You're right regarding the right part evaluation, but you're missing a detail regarding the assignment.
Run this :
i = i++;
or this :
i += i++;
After both operations, i still has its original value.
That's because i is evaluated on the left before the right part of the assignment.
So in your case, you're adding 8 to 1, not to 4.
it's very easy to understand how it works if you imagine it how java stores values in registers! he puts 1 in the first register, and than goes through = sign, and increments the i(++i), so now in i you have 2, and in the second register you have 2, but the first register is not updated, in the third register you'll have 2 and then i is incremented, and then i is incremented and in the last register you'll have 4. So you'll have something like this
1 = 2 + 2 + 4 == 9
The code
int i = 1;
i += ++i + i++ + ++i
is equivalent to
int tmp1 = i // 1, +=
i ++; // 2
int tmp2 = i; // 2
int tmp3 = i; // 2
i ++; // 3
i ++; // 4
int tmp4 = i; // 4
i = tmp1 + tmp2 + tmp3 + tmp4; // 9
i += ++i + i++ + ++i;
i=1 at start
i += X -> i = i + X -> i = 1 + X (so lets count X)
++i will be incremented to 2 and return 2
i++ will return 2 and then be incremented to 3
++i will be incremented from 3 to 4 and return 4
X = 2 + 2 + 4 = 8
So i = 1 + 8 -> i=9
You would get 12 if your code would be something like this
int i = 1;
int tmp = ++i + i++ + ++i;
i += tmp;
because then your code would be i=1, and after calculating tmp i would be i=4, then i+=tmp -> i=4+8=12
Related
I'm new to recursion and don't understand how it works.
This was a classwork problem that had the answer 18, but I don't understand how. From what I know, this should return 6 + 5 + 4 + 3 (3 + m-1 on the recursive line)?
Are the subtraction signs not indicative of subtraction? (assuming that m = 5)
public int test(int m)
{
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
return value;
}
6 + 5 + 4 + 3 (3 + m-1 on the recursive line)? Are the subtraction
signs not indicative of subtraction?
No the +3 will happen for every one of the recursive calls, actually what your function is doing is given the value of (m times 3) + 3.
So for m=5 the recursive calls will be like:
Is m = 0 ? No so let us called recursively:
test(4) + 3
m = 4; then test(3) + 3 + 3
m = 3; then test(2) + 3 + 3 + 3
m = 2; then test(1) + 3 + 3 + 3 + 3
m = 1; then test(0) + 3 + 3 + 3 + 3 + 3
m = 0; then exit with 3 + 3 + 3 + 3 + 3 + 3
Hence, for m=5 you get 18.
A side-note you can use the ternary operator to simplify your method to:
static public int test(int m) {
return (m == 0) ? 3 : test(m - 1) + 3;
}
For visualizing what happens, scatter the code with messages:
public int test(int m)
{
System.out.println("entering test("+m+")");
int value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
System.out.println("returning "+value+" from test("+m+")");
return value;
}
Of course this is just the minimal program, you could also show which branch of the if was taken, m-1, and so on.
JavaScript equivalent, so it can run here in the browser:
function test(m) {
console.log("entering test(" + m + ")");
var value;
if (m == 0)
value = 3;
else
value = test(m - 1) + 3;
console.log("returning " + value + " from test(" + m + ")");
return value;
}
console.log("result: "+test(3));
On the longer run it is a good idea to learn using the debugger of the environment you are using. Among other things, debuggers can step through code line-by-line.
public class Main {
public static void main(String[] args) throws IOException {
int i;
int sum=0;
for(i=1;i<=5;sum+=i++)
System.out.println(sum);
}
...
}
Actual Output:15
I don't know how it did the math?
The syntax for the for loop is:
for ( [ForInit] ; [Expression] ; [ForUpdate] ) Statement
and is basically equivalent with the following while loop:
[ForInit]
while (Expression) {
Statement
[ForUpdate]
}
That mean that all the following are the same:
for(i=1;i<=5;sum+=i++);
i = 1;
while (i <= 5) {
sum += i++;
}
i = 1;
while (i <= 5) {
sum += i;
i++;
}
for (i = 1; i <= 5; i++)
sum += i;
So it is calculating 1 + 2 + 3 + 4 + 5 = 15
What confuses you is the part
sum += i++
In this statement, first sum=sum+i gets calculated. Once sum has been calculated, value of i is incremented by 1.
Since the loop runs five times, previous value of sum gets added to current value of i, which keeps increases by 1.
Try printing out each iteration through the loop to help you visualise what is going on. Swap your for loop for this.
for(i=1;i<=5;sum+=i++)
{
System.out.println("sum = " + sum);
System.out.println("i = " + i);
}
In this code, the statement sum+ = i++ means sum = sum + i++ In this statement, every sum printed in the loop adds to one increment of i and when the loop ends it will display 15.
So it is calculating 0 + 1 + 2 + 3 + 4 + 5 = 15
I am currently reading Barry Burd's Java For Dummies, and came upon this little exercise.
The exercise is regarding post and pre-increment. In the problem (please see the code) I was able to figure out the answers to all the lines(without the help of compiler) except for the last one. Which does not make sense according to my knowledge of post/pre-increment so far.
Please advise on how or why the result is not what I expected.
I tried initializing and declaring a new variable (int) with the value of "20" and then did "i = i++ + i++", but still received the same result (41).
Also tried doing out.println(i) twice, but it still printed 41.
import static java.lang.System.out;
public class Main
{
public static void main(String[] args) {
int i = 10;
out.println(i++); //10(post11)
out.println(--i); //10(pre11-1)
--i; //9(pre10-1)
i--; //9(post8)
out.println(i); //8
out.println(++i); //9(pre8+1)
out.println(i--); //9(post8)
out.println(i); //8
i++; //8(post9)
i = i++ + ++i; //i = 9(post10) + 10(pre9+1) = 19(post20)
out.println(i); //20
i = i++ + i++; //i = 20(post21) + 20(post21) = 40(post42)
out.println(i); //41 (result copied from compiler)
}
}
I expected the last line to print 42 rather than 41, since "20" gets added twice, and also gets incremented twice.
i = i++ + i++
This evaluates to (if i is 20):
i = 20 + 21
Since the first i++ is a post operator, and so doesn't affect it. However, it does affect the next usage of i.
I'll break it down step by step:
i =i+++ i++;, i == 20
i =20+ i++, i == 21
i = 20 +i++, i == 21
i = 20 +21, i == 22
i =41
When you use the assignment operator (=) it is done after the post increment operator. As such you get this:
int i = 10;
i = i++;
System.out.println(i); // print 10
When you are using the post increment twice in the same line, it is not increased after the line is completed, but after the instruction is completed (the instruction being i++). Thus, when doing i = i++ + i++; you are in fact doing this :
i = i++ + i++; // i=20 Original code
i = 20 + i++; // i=21 The first i++ return 20 then increment i to 21
i = 20 + 21; // i=22 The second i++ return 21 then increment i to 22
i = 41; // i=22 The addition is computed
41; // i=41 and assigne to i
It all as to do with operator precedence.
You can see what is happening by writing your own print routine.
int i = 9;
i = print(i++) + print(++i); // i = 9(post10) + 10(pre9+1) = 19(post20)
System.out.println("\n" + i); // 20
i = print(i++) + print(i++); // i = 20(post21) + 20(post21) = 40(post42)
System.out.println("\n" + i); // 41 (result copied from compiler)
public static int print(int i) {
System.out.print(" i = " + i + " ");
return i;
}
I am just very confused from this homework problem. I do not understand why the values of i and sum come out this way. I just do not understand the concept of the algorithm here, can someone please explain this?
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
The output is:
5
10
----jGRASP: operation complete.
5 - because there are 5 iterations
10 - because the sum is 10 :)
Sum
Iteration 1: 0 + 0 = 0
Iteration 2: 0 + 1 = 1
Iteration 3: 1 + 2 = 3
Iteration 4: 3 + 3 = 6
Iteration 5: 6 + 4 = 10
Verification code
int i = 0;
int sum = 0;
for (i = 0; i < 5; i++) {
System.out.println(String.format(
"Iteration %s: %s + %s = %s", (i + 1), sum, i, (sum + i)));
sum += i;
}
This code :
int i = 0;
int sum = 0;
for(i=0; i < 5; i++)
{
sum += i;
}
System.out.println(i + "\n" + sum);
output in sum this : 0 + 1 + 2 + 3 + 4 which is equal to 10 and i the number of iterations = 5.
You have created a variable i with value of 0 and then incrementing it 5 times in for-loop. So you got i's value as 5.
Now the value of sum is 0+1+2+3+4 which is 10
Because you iterate through your loop, which makes i == 5, then print it,
Sum goes as below, you are adding i to the previously calculated sum
0 + 1 = 1
1 + 2 = 3
3 + 3 + 6
6 + 4 = 10
Try put your print command inside the loop, they you can see better what's going on.
The only non-obvious thing is (in my opinion): i will be 5, because you used i++, which also incremented i by 1 even though the body did not execute after the last iteration. Inside the body i only can be maximum 4.
int sum = 0; int i = 0;
for (i = 0; i < 5; i++)
{
sum += i;
if (i == 5)
System.out.println("never executed");
};
Other answers tell the other things.
Im trying to check if a string (important that it is a string) that im reading is correct accoring to the rules of ISBN-13. I found a formula
For example, the ISBN-13 check digit of 978-0-306-40615-?
is calculated as follows:
s = 9×1 + 7×3 + 8×1 + 0×3 + 3×1 + 0×3 + 6×1 + 4×3 + 0×1 + 6×3 + 1×1 + 5×3
= 9 + 21 + 8 + 0 + 3 + 0 + 6 + 12 + 0 + 18 + 1 + 15
= 93
93 / 10 = 9 remainder 3
10 – 3 = 7`
My problem is i don't know how to multiply one number with 1 and every other with 3 ? Im guessing a for-loop but i don't know how to start.
You could "simply" use regular expressions:
ISBN(-1(?:(0)|3))?:?\x20+(?(1)(?(2)(?:(?=.{13}$)\d{1,5}([ -])\d{1,7}\3\d{1,6}\3(?:\d|x)$)|(?:(?=.{17}$)97(?:8|9)([ -])\d{1,5}\4\d{1,7}\4\d{1,6}\4\d$))|(?(.{13}$)(?:\d{1,5}([ -])\d{1,7}\5\d{1,6}\5(?:\d|x)$)|(?:(?=.{17}$)97(?:8|9)([ -])\d{1,5}\6\d{1,7}\6\d{1,6}\6\d$)))
You have 6 pairs of (even,odd) numbers, so go through them pairwise.
for (i = 0; i < 6; i++) {
even += array[2*i];
odd += array[2*i+1]*3;
}
checkbit = 10 - (even+odd)%10;
assuming your inputString is ascii:
int odd = 0;
int even = 0;
char[] c = (inputString + "00").replaceAll("[\\-]", "").toCharArray();
for (int i = 0; i < (c.length - 1) / 2; ++i) {
odd += c[2 * i] - 48;
even += c[2 * i + 1] - 48;
}
int result = 10 - (odd + 3 * even) % 10;
This seems to work effectively and is clear.
// Calculates the isbn13 check digit for the 1st 12 digits in the string.
private char isbn13CheckDigit(String str) {
// Sum of the 12 digits.
int sum = 0;
// Digits counted.
int digits = 0;
// Start multiplier at 1. Alternates between 1 and 3.
int multiplier = 1;
// Treat just the 1st 12 digits of the string.
for (int i = 0; i < str.length() && digits < 12; i++) {
// Pull out that character.
char c = str.charAt(i);
// Is it a digit?
if ('0' <= c && c <= '9') {
// Keep the sum.
sum += multiplier * (c - '0');
// Flip multiplier between 1 and 3 by flipping the 2^1 bit.
multiplier ^= 2;
// Count the digits.
digits += 1;
}
}
// What is the check digit?
int checkDigit = (10 - (sum % 10)) % 10;
// Give it back to them in character form.
return (char) (checkDigit + '0');
}
NB: Edited to correctly handle the 0 check digit. See Wikipedia International Standard Book Number for example isbn with check digit of 0.
Paul
Similar, with loop and awful char-to-string-to-int conversions ;]
boolean isISBN13(String s){
String ss = s.replaceAll("[^\\d]", "");
if(ss.length()!=13)
return false;
int sum=0, multi=1;
for(int i=0; i<ss.length()-1; ++i){
sum += multi * Integer.parseInt(String.valueOf(ss.charAt(i)));
multi = (multi+2)%4; //1 or 3
}
return (Integer.parseInt(String.valueOf(ss.charAt(ss.length()))) == (10 - sum%10));
}