While everybody would naturally accept the following lines of code on grounds of reference equality and value equality and that String and wrappers override the equals method, it takes some effort at first to accept the behavior of Arrays.equals and Arrays.deepEquals
So, it just loops through the given arrays, does a equals on each of the pairs. This means that if you are passing in a String/Wrapper array or any other arrays whose equals method is overridden, then they are equal. Non-equals-overridden classes (derived from Object) will return false.
Arrays.deepEquals looks really deep
From the source, we could understand that Arrays.deepEquals
Loops through the input arrays, gets each pair
Analyses the type of each pair
Delegates the equal deciding logic to one of the overloaded Arrays.equals if they are one of the primitive arrays
Delegates recursively to Arrays.deepEquals if it is an Object array
Calls the respective object’s equals, for any other object
Arrays.deepEquals
12345678910111213141516171819202122232425
for(inti=0;i<length;i++){Objecte1=a1[i];Objecte2=a2[i];if(e1==e2)continue;if(e1==null)returnfalse;// Figure out whether the two elements are equalbooleaneq;if(e1instanceofObject[]&&e2instanceofObject[])eq=deepEquals((Object[])e1,(Object[])e2);elseif(e1instanceofbyte[]&&e2instanceofbyte[])eq=equals((byte[])e1,(byte[])e2);……elseeq=e1.equals(e2);if(!eq)returnfalse;}returntrue;
Now, the Awesome stuff !!
Equals not overridden (nested and non-nested)
While doing an Arrays.equals for nested or non-nested ‘non-overridden equals’ objects, it is safe to assume that if Arrays.equals return false, then Arrays.deepEquals also return false.
While doing an Arrays.equals for non-nested ‘overridden equals’ objects, it can be said that if Arrays.equals is true, then Arrays.deepEquals also return true.
since they are just one-to-one equals call on each pair.
Nested
Interesting scenario : While doing an Arrays.equals for nested ‘overridden equals’ objects, if Arrays.equals is false, then Arrays.deepEquals need not be false.
Consider two Object arrays which has two values - a String and a String array
The result for Arrays.deepEquals is logical since each (from the source), the method loops through each pair of elements, checks whether it is an array type and calls deepEquals on each of the pair. If it is an non-array type, then it just calls the equals on the object.
However, the result of Arrays.equals is tricky but at the same time obvious. The Arrays.equals method blindly calls equals on each pair and since the second arguments String[] are of Object type (whose equals is not overridden), it checks for reference equality and fails !!
When I wrote this write-up on evaluating an infix expression having multiple digits, I was lazy to do it for expressions with parentheses. So, here it comes.
Just like the non-paranthesized version, this algorithm is just the two stack algorithm modified to accommodate parentheses and multiple digits. Floating points aren’t supported intentionally nor is tested. However, I don’t see any reason why it should not work (provided you change the variable types to accommodate a floating point number).
The algorithm goes like this :
1. Initialize two stacks - one for holding values and one for holding operators
2. Read the input expression from left to right - one character at a time.
3. If the character is a space, ignore
4. If the character is a number, then append it to an accumulating variable
(don't push it to the stack yet)
5. If the character is an operator or a right parenthesis, push the accumulated number
to the value stack and reinitialize the accumulator.
5a. If the current operator is a left parenthesis, push it to the expression stack
and continue to the next character in the expression.
5b. If the current operator is a right parenthesis, then evaluate the stacks
until the first left parenthesis is reached. Push the result back to the value stack
5b. If the current operator is of higher precedence than the first item in the operator stack,
then safely ignore and read further.
5c. If the current operator is of lower precedence than the first item in the operator
stack (peek view), then evaluate the previous set (two from value stack and one
from operator stack) and insert the result into the value stack
5d. Finally, insert the current operator to the operator stack
Note : the operator level for right parenthesis is kept at ‘0’ to retain operator precedence while the operator level of left paranthesis is kept at ‘3’ (or anything higher than all the operators) to be the least in the precedence. The only purpose of storing the left brackets in the expression stack is for identifying the beginning of the paranthesized sub-expression.
If you are looking for evaluating an infix expression with parantheses, don’t waste your time here. Visit my other fresh write up here
These images have been running around Facebook for a while now. Though it is eye-damaging primary level arithmetic, it is kind of sweet to write it as a program. Just for the fun of it, I created an html page driven by a javascript implementation. Here is the link.
So, essentially the idea is to evaluate the infix notation in a natural way - respecting the operator precedence. (If you consider this as a puzzle, then there are other variations which involves evaluating the expression in such a way that the result is a maximum value/minimum value)
Please note that the algorithm (and therefore, the program), as it stands does not handle parentheses. This is just a two-stack algorithm with a small variation to accommodate numbers more than a digit.
The algorithm goes like this :
1. Initialize two stacks - one for holding values and one for holding operators
2. Read the input expression from left to right - one character at a time.
3. If the character is a space, ignore
4. If the character is a number, then append it to an accumulating variable
(don't push it to the stack yet)
5. If the character is an operator, push the accumulated number to the value stack and
reinitialize the accumulator.
5a. If the current operator is of higher precedence than the first item in the operator stack,
then safely ignore and read further.
5b. If the current operator is of lower precedence than the first item in the operator
stack (peek view), then evaluate the previous set (two from value stack and one
from operator stack) and insert the result into the value stack
5c. Finally, insert the current operator to the operator stack