This question already has answers here:
How do the post increment (i++) and pre increment (++i) operators work in Java?
(14 answers)
Closed 1 year ago.
New to JAVA, and I know there have been some discussions about ++i and i++, but I still don't know how to approach the question below and how to explain the answer. I shared what I think, but I hope you can help correct what's wrong with my thinking. Thank you very much!
The question is:
Give the results of the following java program.
int z = -1;
system.out.println(++z);
(My thinking: pre-increment, which is incrementing the value of i by 1, so the output is -1+1 = 0)
system.out.println(z--);
(My thinking: pre-decrement, which is decrementing the value of i by 1, so the output is -1-1 = -2, but why is 0? )
system.out.println(z++ + z);
(My thinking: post-increment, which is incrementing the value of i by 1.So the entire thing reads as (z++ plus z). So z++ is 0, + (plus) z, which is 0 + (-1), so the output is -1)
system.out.println(z + z++);
(My thinking: the entire thing reads as (z plus z++). So z is -1, plus z++, which is 0, so the output is -1, but the answer is 0.)
The answer is: 0 0 -1 0
What the answer would be if we changed every + to -?
int z = -1;
system.out.println(--z);
system.out.println(z-- - z);
system.out.println(z - z--);
After reading lots of discussions, I still feel confused. Really hope to learn to understand the concepts. Thank you!
(My thinking: pre-decrement, which is decrementing the value of i by
1, so the output is -1-1 = -2, but why is 0? )
Its not pre-decreement, its post-decreement. For clarity :
++a -> pre-increement
a++ -> post-increement
--a -> pre-decreement
a-- -> post-decreement
int z = -1;
System.out.println(++z);
// ++(-1) => 0; z = 0
System.out.println(z--);
// (0)-- => 0; z = -1
System.out.println(z++ + z);
// (-1)++ + (0) => -1; z = 0
System.out.println(z + z++);
// (0) + (0)++ => 0; z = 1
What the answer would be if we changed every + to -?
I think it would be a nice exercise for you, try it on our own and check by writing a java program for it
The major difference between per-increment and post-increment operation is that the time assignment takes place. in pre-inc operation increment happens before operation. but in post increment first operation then increment. Try to run the below code.
System.out.println(++z);// ++z means z=z+1 hence o/p 0
System.out.println(z--); here first print value 0. then increment happens
System.out.println(z);//here you will get the value -1
System.out.println(z++ + z);//now the value of z is-1 value inc+z 's value
//-1+0 will give -1
System.out.println(z);// assignment happens later here value is 0
System.out.println(z + z++);//0+0=prints 0 later increment
System.out.println(z);// final value for z is 1
Related
This question already has answers here:
Is there a difference between x++ and ++x in java?
(18 answers)
Java: pre-,postfix operator precedences
(5 answers)
Closed 6 years ago.
Say we have Java code below:
int x = 1;
int y = x + x++;
'Cause the precedence of "postfix-increment" operator is higher than "add" operator. I think x++ should be calculate and evaluated first. Then it comes to x + (x++). So the y should be "new_x(2) + 1 = 3".
Though it turns out "2" instead of "3". Any ideas? Thanks.
This question is greatly different from Is there a difference between x++ and ++x in java?. That question mentions nothing about the operator precedence.
Someone has explained that expression is read from left to right. Does it conflict with the precedence of those operators?
Just as I mentioned before, I think x++ should be calculated first. It seems that I mess up with the "evaluation" and "calculation".
The difference between x++ and ++x is quite evident and known. ++ can be used as preadd (Add 1 and then use x ) or postadd (use x and add 1).
Check this out.
As tested and seen
1. x + x++ will give 2
2. x + ++x will give 3
3. x++ + x will give 3
4. ++x + x will give 4
Now the interesting case here is 2nd and 4th which basically explains pre-add operator.
In these cases, the value of x is incremented first and then used in both the places.
However in case of test 2 the first operand i.e. x is already used up for addition so the answer is 3
while in the test 4 the operand x is first incremented and used in both the operands. This happens because the expressions are evaluated from left to right.
x++ would first return x then increment x.
++x would increment x first then return x.
Therefore :
int y = x + x++; //y (2) = x(1) + x(1, then becomes 2 right after)
int y = x + ++x; //y (3) = x(1) + x(becomes 2 before being returned)
Task: We are given two strings of the same length, m and n. We want to modify m into n. We can perform two operations;
We can take a contiguous segment of the current string and either shift each letter in the segment forward in the alphabet once, or backward in the alphabet.
We want to complete this in the minimum number of steps, the goal is an O (n) algorithm.
So here's my first stab at it; obviously not even close to being as optimized as it could be, but I'm kind of lost as to how to optimize it. I'm not sure how to determine what segment of letters would be best to take. My implementation just goes through one letter at a time currently.
public static void shift(String m, String n) {
char mChar[] = m.toCharArray();
char nChar[] = n.toCharArray();
int count = 0;
for (int i = 0; i < m.length(); i++){
while (mChar[i] != nChar[i]){
if (mChar[i] - nChar[i] < 0){
//System.out.println("SHIFT FORWARD");
mChar[i]++;
count++;
}
else{
//System.out.println("SHIFT BACKWARD");
mChar[i]--;
count++;
}
System.out.println(mChar[i]);
}
}
System.out.println(mChar);
System.out.println(count);
}
Also what would be the time complexity of this algorithm as is? The For loop makes it at the minimum O (n), and the while loop could run 25 times in the worst case (if we had 'y' and wanted 'a'). Am I right in this thinking?
Since you're supposed to learn how to program, I won't give you the code, but I can help you with the right algorithm in this case.
I'll do it by example:
shift( "AAAAZZZZ", "BCDBZYYX" )
The goal here is to minimize the number of shift operations, so you need to optimize the block size being shifted.
First, identify the number of shifts needed for each character:
A A A A Z Z Z Z
B C D B Z Y Y X
+1 +2 +3 +1 0 -1 -1 -2
Starting at the first position, if the shift is positive, find the largest consecutive block of positive shifts. If negative, find block of negative shifts. Apply shift. Repeat until zero, and go to next character.
1: Index 0 to 3, shift up:
B B B B Z Z Z Z
0 +1 +2 0 0 -1 -1 -2
2: Index 1 to 2, shift up:
B C C B Z Z Z Z
0 0 +1 0 0 -1 -1 -2
3: Index 2, shift up:
B C D B Z Z Z Z
0 0 0 0 0 -1 -1 -2
4: Index 5 to 7, shift down:
B C D B Z Y Y Y
0 0 0 0 0 0 0 -1
5: Index 7, shift down:
B C D B Z Y Y X
0 0 0 0 0 0 0 0
Done in 5 shift operations.
Update
Optimization: Program doesn't need to "identify the number of shifts" up front, or at all. That was mostly done to help illustrate the algorithm.
Although #Andreas 's answer is viable, it's not O(N). You want to think about the worst case when you then in the minute details it'll be..
How to implement Andreas's answer
you need to know the size of the gaps, so not where it changes indices, but the blocks themselves. Have 2 temp variables -> int startIndex, endIndex...
startIndex = 0, endIndex = -1 at first, and then when you see the sign change, change endIndex = i, record that block length i-startIndex in your blockSize[] append...
then when you see another change, startIndex = endIndex, endIndex = i, record i-startIndex in your blockSize[] append...
When you're done with that, the answer-producing block of code goes like this...
Thinking...
"I need to increment... the last 4 blocks.. let's go through our array which might be size N, let's see.. okay the last 4 is biggest block, now let's go increment the last 4"
Now why is that bad?
You need to go through that size N array everytime you go through the incrementing process, which is why it leads to N^2, do you see what I mean? for big Oh, you always need to think of the literal worst case, which in yours is
[1, -1, 1, -1, 1, -1]
what will you do then? You'll create a gap size array of
[1,1,1,1,1,1]
and then you'll have to go through those gap size array N times to find thebiggest size which is actually any of them so then you'll go through N times to find the biggest size through an N sized, alternating array hence N^2.
Here's another method, but I'm not completely sure if it'll be O(N) or O(N*k), where k is factoring in the # of processes required to shift one letter by one(because you specified that).
[1, -1, 1, -1, 1, -1]
remove 1 from everything
[0, -2, 0, -2, 0, -2]
next time you remove 2 from everything EXCLUDING the 0's
(keep track of the 0's in another array as a flag)
[0,0,0,0,0,0] is your 2nd run through of the array
so 2 shifting operations as opposed to 36
Of course, doing it my method has its worst case too, shown below:
[1, 4, 12, -3, -2, 3] let's say...
1st. [0,3,11,-4,-3,2]
2nd. [0,0,8,-7,-6,-1]
3rd. [0,0,0,-15,-14,-9]
This will lead to a total of 6 operations, but the indices to increment has almost quadrupled in the last 3. I don't know if you're going straight from a -> z, or a->b->c... If it's the former, then I don't think the avalanche effect will be significant.
I can't think of any O(N) operations other than this, which require k to be constant.
When someone answers a question regarding big O computational speed, you should always think of this phrase:
A description of a function in terms of big O notation usually only
provides an upper bound on the growth rate of the function. Associated
with big O notation are several related notations, using the symbols
o, Ω, ω, and Θ, to describe other kinds of bounds on asymptotic growth
rates. - Wikipedia
Although #Andrea's answer is elegant and on average probably performs well, it's not O(N) because the upper bound on the growth rate can be much higher than you expected.
I want to normalize a value between -x and x to -1 and 1.
I thought about value / Math.abs(value), but the problem is if
value is 0 that doesn't work.
Is there a possibility without if and else, so with one operation?
Maybe i should add, that the value only can be -x, x, or 0. nothing between.
value / Math.abs(x)
is what you need. x should never be zero obviously.
Also you should think how to handle the case when value > x.
Take a look at the java.lang.Integer class. There are some nice static methods to help you out, mainly Integer.signum(int)
That will do the job, if you want 0 to convert to 1 too, add a check for 0:
int x = value == 0 ? 1 : Integer.signum(value);
Edit: Long contains likewise methods that do the job with long.
Alternately, no-if code; probably slower, but OP specifically asked for it:
final static int[] TABLE = { -1, 1 (or 0), 1 };
int x = TABLE[Integer.signum(value) + 1];
Lets assume you only want the sign of the number. You can use
double sign = Math.signum(x);
Note: this return NaN for NaN and 0 for 0.
If you expect 0 to return a different value there alternatives.
Note: a condition might be simpler/clearer. e.g.
int sign = x < 0 ? -1 : +1;
or
int sign = x > 0 ? +1 : x < 0 : -1 : 0;
Here's a mathematic method, I started from -5 to 5 and converted in -1 to 1
max=1;
min=-1;
maxold=-5;
minold=5;
value=2;
newvalue= (max-min)/(maxold-minold)*(value-minold)+min;
alert(newvalue);
I am very new to Java (4 weeks, 4 days a week), with zero prior programming knowledge. Can someone explain how this prints 32?
int a = 10;
a = a++ + a + a-- - a-- + ++a;
System.out.println(a);
a++ > means use then change .. So value of a is used first = 10 and then incremented = 11
++a > means change then use. So value of a is first changed then used.
So a = a++ + a + a-- - a-- + ++a;
= (10)
+ (11 [since a is incremented after use])
+ 11 [since a-- = use then change = 11, after -- becomes 10]
- 10 [since value of a is now decremented, and then decremented again, so a = 9 at this point]
+ 10 [since ++a is change then use]
in summary
a = 10 + 11 + 11 - 10 + 10 = 32.
Hope it helps :)
Let's take this one step at a time.
a++ will increment a by one.
a++ +a will take the (11)+ the existing a(10), to give 21
Another iteration will set a to 30, with a decremented by 1 at the end.
- a-- will subtract 1 from a, and subtract this from the value. So -9,
This one is the real trick. a is incremented before any other operation starts. So a becomes 11, before everything else even calculates.
Bottom line, this simplifies to:
4*a-a-2+1= 3*a-1, where a=11 because it has been incremented before anything started (++a).
If instead you moved the ++ to the other side of the ++a, you'd have 29, which is much easier to understand where it comes from.
Easy:
a = 10 + 11 + 11 - 10 + 10 = 32.
It's clearer with parentheses added:
a = (a++) + (a) + (a--) - (a--) + (++a);
The ++ and -- are evaluated based on where they are in relation to the variable, if it is a++ then a is first evaluated, then it is incremented. If you have ++a, then a is incremented and then evaluated.
So a++ + b will take a and add it to be, and then increment it,
while,
++a + b will first increment a, and then add it to b.
In simple
public static int i = 10;
is indicating that the integer i has a value of 10.
then saying
i++;
will make i's value 11, so it just like saying 10 + 1
saying
i--;
will makes i's value 9, so its like saying 10 - 1.
then
i = i + 1;
will do the same as i++;
but its used like i = i + 20; in most cases to take its value and add 20 to it.
same for
i = i - 20;
but taking away instead of adding.
then
a + a;
that will double a.
Hope this helps, Luke.
How can you write the following statement in the given languages?
a(0) = 1
a_(n+1) = 1 - 1 / ( a_n + 3)
I need to find the smallest value of n when a_n -> 0.732050....
My attempt in Mathematica
a[(x+1)_] = 1 - 1/(a[x_] + 3)
The problem is apparently in this a[(x+1)_].
However, I do not know how to do it iteratively in Mathematica.
Mathematica
a[0] = 1;
a[n_] := a[n] = 1 - 1/(a[n-1] + 3)
(Note the memoization trick.)
Also, a[n] converges (very quickly) to sqrt(3)-1:
Solve[x == 1 - 1/(x+3), x]
Python, simplest:
def a(n):
if n == 0: return 1
return 1 - 1 / float(a(n-1) + 3)
# limit is sqrt(3) - 1
limit = 3.0 ** 0.5 - 1.0
# get 9 digits' precision
i = 0
while abs(a(i) - limit) > 1.0e-9:
i += 1
print i
This emits 8, suggesting that optimizations such as recursion elimination or memoizing are likely not warranted.
Of course normally we'd want to get the limit numerically rather than analytically, so the normal way to loop would be rather different -- and best encapsulated in a higher-order function...:
# get a function's limit numerically
def limit(f, eps=1.0e-11):
previous_value = f(0)
next_value = f(1)
i = 2
while abs(next_value - previous_value) > eps:
previous_value = next_value
next_value = f(i)
i += 1
return next_value
Nontrivial looping logic is usually best encapsulated in a generator:
def next_prev(f):
previous_value = f(0)
i = 1
while True:
next_value = f(i)
yield next_value, previous_value
i += 1
previous_value = next_value
with the help of this generator, the limit HOF becomes much simpler:
def limit(f, eps=1.0e-11):
for next_value, previous_value in next_prev(f):
if abs(next_value - previous_value) < eps:
return next_value
Note how useful the separation is: next_prev embodies the concept of "get the next and previous value of the function", limit just deals with "when should the loop terminate".
Last but not least, itertools often offers a good alternative to generators, letting you encapsulate finicky iteration logic in speedy ways (though it does take some getting used to...;-):
import itertools
def next_prev(f):
values = itertools.imap(f, itertools.count())
prv, nxt = itertools.tee(values)
nxt.next()
return itertools.izip(prv, nxt)
Java
double A = 1;
int n = 0;
while (true) {
System.out.println(n + " " + A);
A = 1 - 1 / (A + 3);
n++;
}
Python
A = 1.0
n = 0
while 1:
print n, A
A = 1 - 1 / (A + 3)
n += 1
Mathematica:
a[0] := 1
a[k_] := 1 - 1/(a[k - 1] + 3)
I substituted k = n + 1 because that makes the expression simpler. The result is equivalent.
Python
next = lambda x: 1.0 - (1.0 / (float(x) + 3.0))
last, z, count = -1, 0.0, 0
while last != z:
print count, z
last, z, count = z, next(z), count+1
I try to avoid writing "while True" or such if I can avoid it. Almost certainly no code that I write will loop forever. In this case, it ran sixteen times for me. Sixteen is a lot less than ℵ-null.
A one-liner in Mathematica which gives a list of exact elements of your sequence:
In[66]:= NestWhileList[1 - 1/(#1 + 3) &, 1,
RealExponent[Subtract[##]] > -8 &, 2]
Out[66]= {1, 3/4, 11/15, 41/56, 153/209, 571/780, 2131/2911, \
7953/10864, 29681/40545}
The difference between the last two elements is less than 10^-8. It thus have taken 8 iterations:
In[67]:= Length[%]
Out[67]= 9