Related
Why are assignment chains are evaluated in right to left order?
i = j = k = 10;
is
k = 10;
j = k;
i = j;
Addition is evaluated left to right:
public static void main(String[] args)
{
int i = m1() + m2() + m3();
}
public static int m1()
{
System.out.println("m1");
return 1;
}
public static int m2()
{
System.out.println("m2");
return 2;
}
public static int m3()
{
System.out.println("m3");
return 3;
}
Output:
m1
m2
m3
According to which rule are assignment operator chains processed in right to left order?
Why? Because that's the most useful order, and seems to conform to most people's expectations, perhaps in part because that's the usual case.
The other way round would be surprising (i.e., a source of bugs):
int k;
j = 42;
i = j = k = 10;
Left to right leaves i at 42, j undefined, and k 10. Right to left makes all 3 variables have the value 10, much more useful.
Which rule? https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.26
Chainable assignment is right-associative (i.e. right to left) simply because that is the only way it would make sense. The operation i = j = k = 10 is supposed to assign 10 to all three variables. If it was done left to right, it would evaluate to
i = j;
j = k;
k = 10;
Rather, than assigning the same value to all three, it would be "shifting" the values: i gets the old value of j, j gets the old value of k, and only k gets the value 10. Now, this could possibly be a useful operation to have, but it is not the intended behaviour here, so it has to be done from right to left.
Also, going left to right would evaluate to ((i = j) = k) = 10, which would be putting an rvalue (the assignment expression as a whole is an rvalue) on the left side of an assignment, which is not allowed.
The evaluation order is specified in the Java Language Specification (JLS). In section 15.26 Assignment Operators is written
There are 12 assignment operators; all are syntactically right-associative (they
group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to
b and then assigns the value of b to a.
This means, that the right-most assignment is performed first, then then next to the left etc.
Generally, the precedence of operations is specified by the grammar of Java. This also specifies why additions are performed after multiplications.
Concerning you first question: It would be quite counter-intuitive to evaluate the assignment in a different order, as the variables could have different values afterwards.
I was going through some exercises but I am confused in this one:
public static int f (int x, int y) {
int b=y--;
while (b>0) {
if (x%2!=0) {
--x;
y=y-2;
}
else {
x=x/2;
b=b-x-1;
}
}
return x+y;
}
What is the purpose of b=y--?
So, for example, x=5 and y=5
when we first go inside of while loop (while (b>0)) will b = 4 or 5? When I am running the code in my computer b is 5. And the return is 3. It is really unclear to me. Sorry if I am unclear in my question.
int b=y--; first assignes b=y and then decrements y (y--).
Also take a look at the prefix/postfix unary increment operator.
This example (taken from the linked page) demonstrates it:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
The difference between a post-increment/decrement and a pre-increment/decrement is in the evaluation of the expression.
The pre-increment and pre-decrement operators increment (or decrement) their operand by 1, and the value of the expression is the resulting incremented (or decremented) value. In contrast, the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation.
In other words:
int a = 5;
int b;
b = --a; // the value of the expression --a is a-1. b is now 4, as is a.
b = a--; // the value of the expression a-- is a. b is still 4, but a is 3.
Remember that a program must evaluate expressions to do everything. Everything is an expression, even just a casual mention of a variable. All of the following are expressions:
a
a-1
--a && ++a
System.out.println(a)
Of course, in the evaluation of expressions, operator precedence dictates the value of an expression just as the PEMDAS you learned in grade school. Some operators, such as increment/decrement, have side effects, which is of course great fun, and one of the reasons why functional programming was created.
I believe b would equal 5 entering the loop because
b=y--;
When the "--" is behind the variable it decrements it after the action.
It's poor coding, as it can confuse new programmers.
The function, assuming it is passing by value, like in the example above (as opposed to passing by reference) takes a copy of y, decrements it, and assigns it to b. It does not alter the argument passed to the function when it was called.
Post increment
x++;
x += 1;
Post decrement
x--;
x -=1;
Pre increment : ++x;
Pre decrement : --x;
According to the Head First Java:
Difference between x++ and ++x :
int x = 0; int z = ++x;
Produces: x is 1, x is 1
in x = 0; int z = x++;
Produces: x is 1, z is 0
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In-place transposition of a matrix
Recently attended an Technical Written Interview. Came through the following question.
I have an array as say
testArray = {a1,a2,a3,...an,b1,b2,b3,....bn,c1,c2,c3,.....,cn}
I need to sort this array as `
testArray = {a1,b1,c1,a2,b2,c2,a3,b3,c3,.....,an,bn,cn}
Constraint is I should not use extra memory, should not use any inbuilt function.
Should write complete code, it can be in any language and can also use any data structure.
eg:
Input: {1,2,3,4,5,6,7,8,9}, n = 3
Output: {1,4,7,2,5,8,3,6,9}
I could not get any solution within the constraint, can anyone provide solution or suggestion?
This is just a matrix transpose operation. And there is even a problem and solution for in-place matrix transposition on Wikipedia.
No extra space is impossible, since you need to at least go through the array. O(1) additional memory is possible, with heavy penalty on the time complexity.
The solution is built on follow-the-cycle algorithm in the Wikipedia page: for each cell, we will find the cell with the smallest index in the cycle. If the cell with the smallest index is greater than or equal (>=) to the index of the current cell, we will perform chain swapping. Otherwise, we ignore the cell, since it has been swapped correctly. The (loosely analyzed) upper bound on time complexity can go as high as O((MN)2) (we go through M * N cells, and the cycle can only be as long as the total number of cells).
Impossibility
It is impossible to implement this algorithm without extra use of memory and an arbitrary length because you need a an iterator to traverse the list and that takes up space.
Finding the right indices to swap
For fixed lengths of the array and fixed n you can use a matrix transpose algorithm.
and in order to swap the elements y
The algorithm you are looking for is a matrix transpose algorithm.
so you have to swap every element exactly once iterating through it.
http://en.wikipedia.org/wiki/Transpose
basically you have to swap the m -th element in the n - th component with the n - th element in the m -th component. This can be done by a double loop.
m = length(array)/n;
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
{
index_1 = i * m + j;
index_2 = j * m + i
swap(index_1, index_2);
}
Note: For fixed m and n this loop can be completely unrolled and therefore m, i, j can be replaced by a constant.
Swaping without Memory consumption
In order to swap every element without using extra space you can use the XOR swap algorithm as pointed out in the comments:
X := X XOR Y
Y := Y XOR X
X := X XOR Y
The simplest way to swap two numbers (a and b) without using a temporary variable is like this:
b = b + a;
a = b - a;
b = b - a;
If you write that in a function, then you're part of the way there. How you keep track of which variable to swap within the arrays without using a temporary variable eludes me right now.
Bear in mind voters: he doesn't actually need to sort the array, just swap the right values.
Edit: this will work with large values in Java (and in C/C++ unless you turn on some very aggressive compiler optimisations - the behaviour is undefined but defaults to sane). The values will just wrap around.
Second edit - some (rather untested) code to flip the array around, with I think 4 integers over the memory limit. It's while technically massively unthreadsafe, but it would be parallelisable just because you only access each array location once at most:
static int[] a = {1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16};
static int n = 4;
public static void main(String[] args)
{
for(int i = 0; i < a.length/n; i++) // 1 integer
for(int j = 0; j < n; j++) // 1 integer
if(j > i)
swap(i*n+j, j*n+i);
}
static void swap(int aPos, int bPos) // 2 integers
{
if(a[aPos] != a[bPos])
{
a[bPos] = a[aPos] + a[bPos];
a[aPos] = a[bPos] - a[aPos];
a[bPos] = a[bPos] - a[aPos];
}
}
Apologies if this misunderstands the question; I read it carefully and couldn't work out what was needed other than this.
Take a look at Quicksort algorithm
For more information about available algorithms, go to Sorting algorithm page.
When you have a circular buffer represented as an array, and you need the index to wraparound (i.e., when you reach the highest possible index and increment it), is it "better" to:
return (++i == buffer.length) ? 0: i;
Or
return ++i % buffer.length;
Has using the modulo operator any drawbacks? Is it less readable than the first solution?
EDIT:
Of course it should be ++i instead of i++, changed that.
EDIT 2:
One interesting note: I found the first line of code in ArrayBlockingQueue's implementation by Doug Lea.
Update: OP has admitted in a comment that it should have been pre-increment instead. Most of the other answers missed this. There lies proof that the increment in this scenario leads to horrible readability: there's a bug, and most people couldn't see it.
The most readable version is the following:
return (i == buffer.length-1) ? 0 : i+1;
Using ++ adds unnecessary side effect to the check (not to mention that I strongly feel that you should've used pre-increment instead)
What's the problem with the original code? Let's have a look, shall we?
return (i++ == N) ? 0 : i; // OP's original, slightly rewritten
So we know that:
i is post-incremented, so when i == N-1 before the return statement, this will return N instead of wrapping to 0 immediately
Is this intended? Most of the time, the intent is to use N as an exclusive upper bound
The variable name i suggests a local variable by naming convention, but is it really?
Need to double check if it's a field, due to side-effect
In comparison:
return (i == N-1) ? 0 : i+1; // proposed alternative
Here we know that:
i is not modified, doesn't matter if it's local variable or field
When i == N-1, the returned value is 0, which is more typical scenario
The % approach
Alternatively, you can also use the % version as follows:
return (i+1) % N;
What's the problem with %? Well, the problem is that even though most people think it's the modulo operator, it's NOT! It's the remainder operator (JLS 15.17.3). A lot of people often get this confused. Here's a classic example:
boolean isOdd(int n) {
return (n % 2) == 1; // does this work???
}
That code is broken!!! It returns false for all negative values! The problem is that -1 % 2 == -1, although mathematically -1 = 1 (mod 2).
% can be tricky, and that's why I recommend the ternary operator version instead. The most important part, though, is to remove the side-effect of the increment.
See also
Wikipedia: modulo operation
Don't ask me to choose between two options which both contain postincrement (*) mixed with expression evaluation. I'll say "none".
(*) Update: It was later fixed to preincrement.
Wouldn't the i++ % buffer.length version have the drawback that it keeps incrementing i, which could lead to it hitting some sort of max_int/max_long/max_whatever limit?
Also, I would split this into
i = (i++ == buffer.length) ? 0 : i;
return i;
since otherwise you'd most likely have a bug.
The first one will give you an ArrayIndexOutOfBoundsException because i is never actually reset to 0.
The second one will (probably) give you an overflow error (or related undesirable effect) when i == Integer.MAX_VALUE (which might not actually happen in your case, but isn't good practice, IMHO).
So I'd say the second one is "more correct", but I would use something like:
i = (i+1) % buffer.length;
return i;
Which I think has neither of the two problems.
I went ahead and tested everyone's code, and was sad to find that only one of the previous posts (at the time of this post's writing) works. (Which one? Try them all to find out! You might be surprised!)
public class asdf {
static int i=0;
static int[] buffer = {0,1,2};
public static final void main(String args[]){
for(int j=0; j<5; j++){
System.out.println(buffer[getIndex()]);
}
}
public static int getIndex(){
// return (++i == buffer.length) ? 0: i;
// return ++i % buffer.length;
// i = (i++ == buffer.length) ? 0 : i;
// return i;
// i++;
// if (i >= buffer.length)
// {
// i = 0;
// }
// return i;
// return (i+1 == buffer.length) ? 0 : i+1;
i = (i+1) % buffer.length;
return i;
}
}
Expected output is:
1
2
0
1
2
Apologies in advance if there's a coding error on my part and I accidentally insult someone! x.x
PS: +1 for the previous comment about not using post-increment with equality checks (I can't actually upmod posts yet =/ )
I prefer the condition approach even if we use unsigned type, modulo operation has drawbacks. Using modulo has a bad side effect when the number tested rolls back to zero
Example:
255 % 7 == 3
So if you use byte (unsigned char) for example, when the number roll after 255 (i.e. zero), it will not result to 4. Should result to 4 (when 256 % 7), so it rotates correctly. So just use testing(if and ternary operator) constructs for correctness
If for achieving performance, and if the number is multiple of 2 (i.e. 2, 4, 8, 16, 32, 64, ...), use & operator.
So if the buffer length is 16, use:
n & 15
If buffer length is 64, use 63:
n & 63
Those rotate correctly even if the number goes back to zero. By the way, if the number is multiple of 2, even the modulo/remainder approach would also fit the bill, i.e. it will rotate correctly. But I can hazard a guess that & operation is faster than % operation.
I think the second solution has the clear advantage that it works, whereas the first does not. The first solution will always return zero when i becomes bigger than buffer.length because i is never reset.
The modulo operator has no drawbacks.
Surely it would be more readable to use an if:
i++;
if (i >= buffer.length)
{
i = 0;
}
return i;
Depends a bit if buffer.length ever changes.
This is very subjective and depends on what your colleagues are used to see. I would personally prefer the first option, as it expresses explicitly what the code does, i.e. if the buffer length is reached, reset to 0. You don't have to perform any mathematical thinking or even know what the modulo does (of course you should! :)
Personally, I prefer the modulo approach. When I see modulo, I immediately think of range limiting and looping but when I see the ternary operator, I always want to think more carefully about it simply because there are more terms to look at. Readability is subjective though, as you already pointed out in your tagging, and I suspect that most people will disagree with my opinion.
However, performance is not subjective. Modulo implies a divison operation which is often slower than a comparison against zero. Obviously, this is more difficult to determine in Java since we're not compiling to native code until the jitter kicks in.
My advice would be write which ever you feel is most appropriate (so long as it works!) and get a colleague (assuming you have one) to asses it. If they disagree, ask another colleague - then go with the majority vote. #codingbydemocracy
It is also worth noting, that if our buffer has length of power of 2 then very efficient bit manipulation will work:
idx = (idx + 1) & (length - 1)
You can use also bit manipulation:
idx = idx & ((idx-length)>>31)
But it's not faster than the if-variant on my machine.
Here is some code to compare running time in C#:
Stopwatch sw = new Stopwatch();
long cnt = 0;
int k = 0;
int modulo = 10;
sw.Start();
k = 0;
cnt = 0;
for ( int j=0 ; j<100000000 ; j++ ) {
k = (k+1) % modulo;
cnt += k;
}
sw.Stop();
Console.WriteLine( "modulo cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
if ( ++k == modulo )
k = 0;
cnt += k;
}
sw.Stop();
Console.WriteLine( "if cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
sw.Reset();
sw.Start();
k = 0;
cnt = 0;
for (int j = 0; j < 100000000; j++) {
++k;
k = k&((k-modulo)>>31);
cnt += k;
}
sw.Stop();
Console.WriteLine( "bit cnt=" + cnt.ToString() + " " + sw.Elapsed.ToString() );
The Output:
modulo cnt=450000000 00:00:00.6406035
if cnt=450000000 00:00:00.2058015
bit cnt=450000000 00:00:00.2182448
I prefer the modulo operator for the simple reason it is shorter. And any program should be able to dream in modulo since it is almost as common as a plus operator.
Why does this
int x = 2;
for (int y =2; y>0;y--){
System.out.println(x + " "+ y + " ");
x++;
}
prints the same as this?
int x = 2;
for (int y =2; y>0;--y){
System.out.println(x + " "+ y + " ");
x++;
}
As far, as I understand a post-increment is first used "as it is" then incremented. Are pre-increment is first added and then used. Why this doesn't apply to the body of a for loop?
The loop is equivalent to:
int x = 2;
{
int y = 2;
while (y > 0)
{
System.out.println(x + " "+ y + " ");
x++;
y--; // or --y;
}
}
As you can see from reading that code, it doesn't matter whether you use the post or pre decrement operator in the third section of the for loop.
More generally, any for loop of the form:
for (ForInit ; Expression ; ForUpdate)
forLoopBody();
is exactly equivalent to the while loop:
{
ForInit;
while (Expression) {
forLoopBody();
ForUpdate;
}
}
The for loop is more compact, and thus easier to parse for such a common idiom.
To visualize these things, expand the for loop to a while loop:
for (int i = 0; i < 5; ++i) {
do_stuff(i);
}
Expands to:
int i = 0;
while (i < 5) {
do_stuff(i);
++i;
}
Whether you do post-increment or pre-increment on the loop counter doesn't matter, because the result of the increment expression (either the value before or after the increment) isn't used within the same statement.
There's no difference in terms of performance, if that's your concern. It can only be used wrongly (and thus sensitive to errors) when you use it during the increment.
Consider:
for (int i = 0; i < 3;)
System.out.print(++i + ".."); //prints 1..2..3
for (int i = 0; i < 3;)
System.out.print(i++ + ".."); //prints 0..1..2
or
for (int i = 0; i++ < 3;)
System.out.print(i + ".."); //prints 1..2..3
for (int i = 0; ++i < 3;)
System.out.print(i + ".."); //prints 1..2
Interesting detail is however that the normal idiom is to use i++ in the increment expression of the for statement and that the Java compiler will compile it as if ++i is used.
++i and i++ makes a difference when used in combination with the assignment operator such as int num = i++ and int num = ++i or other expressions.
In above FOR loop, there is only incrementing condition since it is not used in combination with any other expression, it does not make any difference. In this case it will only mean i = i + 1.
This loop is the same as this while loop:
int i = 0;
while(i < 5)
{
// LOOP
i++; // Or ++i
}
So yes, it has to be the same.
Because that statement is just on it's own. The order of the increment doesn't matter there.
Those two cases are equivalent because the value of i is compared after the increment statement is done. However, if you did
if (i++ < 3)
versus
if (++i < 3)
you'd have to worry about the order of things.
And if you did
i = ++i + i++;
then you're just nuts.
Because nothing in your examples is using the value returned from the pre- or post-increments. Try wrapping a System.out.println() around the ++x and x++ to see the difference.
From the Java Language Specification chapter on for loops:
BasicForStatement:
for ( ForInit ; Expression ; ForUpdate ) Statement
... if the ForUpdate part is present,
the expressions are evaluated in
sequence from left to right; their
values, if any, are discarded. ...
If the ForUpdate part is not present,
no action is taken.
(highlight is mine).
The output is the same because the 'increment' item in the 'for (initial; comparison; increment)' doesn't use the result of the statement, it just relies on the side-effect of the statement, which in this case is incrementing 'i', which is the same in both cases.
Because the value of y is calculated in for statement and the value of x is calculated in its own line, but in the System.out.println they are only referenced.
If you decremented inside System.out.println, you would get different result.
System.out.println(y--);
System.out.println(--y);
The check is done before the increment argument is evaluated. The 'increment' operation is done at the end of the loop, even though it's declared at the beginning.
Try this example:
int i = 6;
System.out.println(i++);
System.out.println(i);
i = 10;
System.out.println(++i);
System.out.println(i);
You should be able to work out what it does from this.
There are a lot of good answers here, but in case this helps:
Think of y-- and --y as expressions with side effects, or a statement followed by an expression. y-- is like this (think of these examples as pseudo-assembly):
decrement y
return y
and --y does this:
store y into t
decrement y
load t
return t
In your loop example, you are throwing away the returned value either way, and relying on the side effect only (the loop check happens AFTER the decrement statement is executed; it does not receive/check the value returned by the decrement).
If the for loop used the result of the expression i++ or ++i for something, then it would be true, but that's not the case, it's there just because its side effect.
That's why you can also put a void method there, not just a numeric expression.
The increment is executed as an independent statement. So
y--;
and
--y;
are equivalent to each other, and both equivalent to
y = y - 1;
Because this:
int x = 2;
for (int y =2; y>0; y--){
System.out.println(x + " "+ y + " ");
x++;
}
Effectively gets translated by the compiler to this:
int x = 2;
int y = 2
while (y > 0){
System.out.println(x + " "+ y + " ");
x++;
y--;
}
As you see, using y-- or --y doesn't result in any difference. It would make a difference if you wrote your loop like this, though:
int x = 2;
for (int y = 3; --y > 0;){
System.out.println(x + " "+ y + " ");
x++;
}
This would yield the same result as your two variants of the loop, but changing from --y to y-- here would break your program.
It's a matter of taste. They do the same things.
If you look at code of java classes you'll see there for-loops with post-increment.
in your case, it's the same, no difference at all.
You are right. The difference can be seen in this case:
for(int i = 0; i < 5; )
{
System.out.println("i is : " + ++i);
}
Yes it does it sequentially. Intialisation, then evaluation condition and if true then executing the body and then incrementing.
Prefix and Postfix difference will be noticable only when you do an Assignment operation with the Increment/Decrement.
There is no differences because every part of the for "arguments" are separated statements.
And an interesting thing is that the compiler can decide to replace simple post-incrementations by pre-incrementations and this won't change a thing to the code.
They DON'T behave the same. The construct with i++ is slightly slower than the one with ++i because the former involves returning both the old and the new values of i. On the other side, the latter only returns the old value of i.
Then, probably the compiler does a little magic and changes any isolated i++ into a ++i for performance reasons, but in terms of raw algorithm they are not strictly the same.
There's many similar posts at Stackoverflow:
Difference between i++ and ++i in a loop?
Is there any performance difference between ++i and i++ in C#?
Is there a performance difference between i++ and ++i in C?
However, it seems your question is more generic because it's not specific to any language or compiler. Most of the above questions deal with a specific language/compiler.
Here's a rundown:
if we are talking about C/C++/Java (probably C# too) and a modern compiler:
if i is an integer (const int, int, etc.):
then the compiler will basically replace i++ with ++i, because they are semantically identical and so it doesn't change the output. this can be verified by checking the generated code / bytecode (for Java, I use the jclasslib bytecode viewer).
else:
else:
all bets are off, because the compiler cannot guarantee that they are semantically identical, so it does not try to optimize.
So if you have a class in C++ that overrides the postfix and prefix operators (like std::iterator), this optimization is rarely, if ever, done.
In summary:
Mean what you say, and say what you mean. For the increment part of for loops, you almost always want the prefix version (i.e., ++i).
The compiler switcheroo between ++i and i++ can't always be done, but it'll try to do it for you if it can.
in a loop, first initialization, then condition checking, then execution, after that increment/decrement. so pre/post increment/decrement does not affect the program code.
About i++ (post-incrementation) vs. ++i (pre-incrementation) #me: "In both cases, the expression gets evaluated, and the result is used to check against the condition. In the pre-increment case, the increment expression increments the variable and returns the resulting value. For post-increment, the increment expression also increments the variable, but it returns the previous value. As a result, pre-increment compares against the incremented value, whereas post-increment compares against the original value; in both cases, the variable has been incremented when the condition is checked." – tdammers
There is quite confusion in between post and pre increment operator, this can be easily understand from this excerpt of "Algorithms, 4th Edition by Robert Sedgewick and Kevin Wayne"
Increment/decrement operators: i++ is the same as i = i + 1 and has the value
i in an expression. Similarly, i-- is the same as i = i - 1. The code ++i and
--i are the same except that the expression value is taken after the increment/
decrement, not before.
for example
x = 0;
post increment:
x++;
step 1:
assign the old value (0) value of the x back to x.So, here is x = 0.
step 2:
after assigning the old value of the x, increase the value of x by 1. So,
x = 1 now;
when try to print somthing like:
System.out.print(x++);
the result is x : 0. Because only step one is executed which is assigning
old value of the x back and then print it.
But when, we do operation like this:
i++;
System.out.print(i);
the result is x: 1. which is because of executing Step one at first
statement and then step two at the second statement before printing the
value.
pre increment:
++x;
step 1:
increase the value of x by 1. So, x = 1 now;
step 2:
assign the increased value back to x.
when try to print something like:
System.out.print(++1)
the result is x : 1. Because the value of the x is raised by 1 and then
printed. So, both steps are performed before print x value. Similarly,
executing
++i;
system.out.print(i);
Both steps are executed at statement one. At second statement, just the
value of "i" is printed.