Java control if else statement - java

I'm using the below free text to learn intro to java and I am having trouble understanding the difference between the code segments:
http://math.hws.edu/eck/cs124/downloads/javanotes7-linked.pdf
Example 1
int x;
x = -1;
if (x < 0)
x = 1;
else
x = 2;
Example 2
int x;
x = -1;
if (x < 0)
x = 1;
if (x >= 0)
x = 2;
In Example 1, x is 1; In Example 2, x is 2.
On the right, if -1 is not > or = to 0 then shouldn't the output be 1? Could someone please explain why the output would instead be 2?

Once the second if statement is evaluated, x the first has already taken effect--so the value of x is now 1.
if (x < 0)
x = 1;
if (x >= 0) //x is 1 because you've already evaluated the above!
x = 2;
The else keyword creates mutually exclusive branches: only one can be executed. So if you had this, the behavior would be as you expected:
if (x < 0)
x = 1;
else if (x >= 0)
x = 2;

In the Example 1, only one of the statements x = 1; or x = 2; will be executed because it uses an if...else statement.
In the Example 2, both statements will be executed because it uses two separate if statements, and because both conditions are true at the time they are evaluated.

In the second example; first you go through the first if condition:
x = -1;
if (x < 0) x = 1;
x is less than 0, so x becomes 1.
When you go to the second if condition:
if (x >= 0) x = 2;
x is still 1, and 1 is greater than 0, so x becomes 2.

Related

Calculate dots on cuboid's grid

I have an issue with my math skills here. So I need to calculate the positions (x, y, z) of a specific amount of dots per aixs. For example take this image
final double gapX = lengthX / dotsPerXAxis;
final double gapY = lengthY / dotsPerYAxis;
final double gapZ = lengthZ / dotsPerZAxis;
for (BlockFace blockFace : BlockHandler.DIRECT_RELATIVES) {
final DecimalVector3D minCorner = new DecimalVector3D(
blockFace.getModX(),
blockFace.getModY(),
blockFace.getModZ()
);
for (int x = 0; x < dotsPerXAxis || x == 0; x++) {
for (int y = 0; y < dotsPerYAxis; y++) {
for (int z = 0; z < dotsPerZAxis; z++) {
}
}
}
My question now is: how can I iterate over all the dots except those that are inside the cuboid and calculate their position and put them in an ImmutableList?
You need to treat point if at least one coordinate of it is zero or dotsPerZAxis.
So set flags - if X-coordinate lies on face, if Y-coordinate lies on face. If both flags are not set - get only the first and the last Z-coordinates, otherwise walk through all Z-coordinates.
Unchecked Java:
for (int x = 0; x < dotsPerXAxis; x++) {
bool atX = (x == 0) || (x == dotsPerXAxis - 1);
for (int y = 0; y < dotsPerYAxis; y++) {
bool atY = (y == 0) || (y == dotsPerYAxis - 1);
int zstep = (atX || atY)? 1: dotsPerZAxis - 1;
for (int z = 0; z < dotsPerZAxis; z+=zstep) {
treat(x,y,z)
}
}
}
Ideone Python working code as proof-of-concept gives n^3 - (n-2)^3 points (26 surface points for n=3, 56 for n=4, 98 for n=5)
Based on the help of MBo I figured this out
for (BlockFace blockFace : BlockHandler.DIRECT_RELATIVES) {
for (int x = 0; x < dotsPerXAxis || x == 0 || x == dotsPerXAxis - 1; x++) {
for (int y = 0; y < dotsPerXAxis || y == 0 || y == dotsPerYAxis - 1; y++) {
for (int z = 0; z < dotsPerXAxis || z == 0;
z += (y == 0 || y == dotsPerYAxis - 1) || (x == 0 || x == dotsPerXAxis - 1) ? 1 :
dotsPerZAxis - 1) {
results.add(new DecimalVector3D(
x,
y,
z
));
}
}
}
}

Is it possible in an "if-statement" to execute the actual statement if the condition is false?

I encountered the code example below in the JavaNotes book. The answer was that after execution the x is equal to 2.
My question is how exactly does this work?
I see it is not an if-else flow, but in the second "if" the boolean expression is false, so X shall not obtain value 2.
How is this happening?
int x;
x = -1;
if (x < 0)
x = 1;
if (x >= 0)
x = 2;
Try rubber duck debugging! Read the comment in the code so you can understand how your code work :
int x;
x = -1;
if (x < 0) { //-1 < 0 = true
x = 1; //enter here -> change x = 1
}//end of the first if
if (x >= 0) {//1 >= 0 = true
x = 2; //enter here -> change x = 2
}//end of the second if
System.out.println(x);//result is 2
If you expect x = 1 then your code should look like this :
if (x < 0) { //-1 < 0
x = 1; //enter here -> change x = 1
} else if (x >= 0) {//1 >= 0
//^^^^------------------------------------------note the else
x = 2; //enter here -> change x = 2
}
x = -1;
first if: x < 0 is true,
so x gets new value 1
second if: x > 0 is true
so x gets new value 2
x = 2;

Find elements surrounding an element in an array

I have a multidimensional array, I want to get the elements surrounding a particular element in that array.
For example if I have the following:
[[1,2,3,4,5,6]
[8,9,7,5,2,6]
[1,6,8,7,5,8]
[2,7,9,5,4,3]
[9,6,7,5,2,1]
[4,7,5,2,1,3]]
How do I find all the 8 elements around any of the above elements? And how do I take care of elements at the edges?
One way I figured out is, to write a 9 line code for this , which is obvious, but is there a better solution?
You can use 'direction array' in form
[[-1,-1], [-1,0],[1,0]..and so on]
And method which takes point coordinate and iterates through direction array -> add direction numbers to coordinates, check indexes are not out of bounds and collect results.
Something like this:
private static int[][] directions = new int[][]{{-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0, -1}};
static List<Integer> getSurroundings(int[][] matrix, int x, int y){
List<Integer> res = new ArrayList<Integer>();
for (int[] direction : directions) {
int cx = x + direction[0];
int cy = y + direction[1];
if(cy >=0 && cy < matrix.length)
if(cx >= 0 && cx < matrix[cy].length)
res.add(matrix[cy][cx]);
}
return res;
}
For (i, j) ->
(i - 1, j - 1)
(i - 1, j)
(i - 1, j + 1)
(i, j - 1)
(i, j + 1)
(i + 1, j - 1)
(i + 1, j)
(i + 1, j + 1)
Now, at the edges, you can check for num % row == 0, then its at row edge...
and , num % col == 0 then its column edge..
Here's is how you can proceed: -
Given an index (i, j).. You can find elements in a rows adjacent to j for i - 1, then i, and then i + 1. (NOTE : - for index i you just have to access j - 1, and j + 1)
Subsequently you also can check for the row edge and column edge..
Here, you can look at the code below, how it can happen: -
// Array size
int row = 6;
int col = 6;
// Indices of concern
int i = 4;
int j = 5;
// To the left of current Column
int index = i - 1;
for (int k = -1; k < 2; k++) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
// In the current Column
index = i;
// Increment is 2 as we don't want (i, j)
for (int k = -1; k < 2; k = k + 2) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
// To the right of current Column
index = i + 1;
for (int k = -1; k < 2; k++) {
if (index % row > 0 && ((j + k) % col) > 0) {
System.out.println(arr[index][j + k]);
}
}
UPDATE : - The above code can further be simplified.. But I leave that task to you..
HINT: - You can reduce one for loop from there..
for (i = 0; i < array.length; i++) {
for (j = 0; j < array[i].length; j++) {
for (x = Math.max(0, i - 1); x <= Math.min(i + 1, array.length); x++) {
for (y = Math.max(0, j - 1); y <= Math.min(j + 1,
array[i].length); y++) {
if (x >= 0 && y >= 0 && x < array.length
&& y < array[i].length) {
if(x!=i || y!=j){
System.out.print(array[x][y] + " ");
}
}
}
}
System.out.println("\n");
}
}
Thanks to all the people who have answered, but i figured it out with the help of this post which i found just now, and above is the solution. thanks again :)
Base case is just to obtain neighbour elements by indexing shifting. For (i,j) it will be (i + 1, j), (i - 1, j), etc.
On the edges I use two approaches:
Modulo % operator to avoid IndexOutOfBounds exception, but it sometimes confuse with wrong elements indexation.
Wrap your matrix with one layer of default elements. It adds some extraspace for holding matrices, but makes your code more readable without catching exception, lot ifs and so on. This trick often used when representation maze as matrix.
Example: your default element is 0.
0 0 0 0 0 0
0 1 2 3 4 0
0 2 6 7 3 0
0 1 3 5 7 0
0 2 4 6 2 0
0 0 0 0 0 0
Note: do not forget iterate through actual array size, not extended.
This is my solution for your problem written in Ruby. Instead of calculating if element is at edge you could access elements "over" the edge and handle "nil" values or exceptions that happen there. Then remove "nil" values from final list. This solution is not as good as calculating if some "point" is over the edge or not.
big_map = [[1,2,3,4,5,6],
[8,9,7,5,2,6],
[1,6,8,7,5,8],
[2,7,9,5,4,3],
[9,6,7,5,2,1],
[4,7,5,2,1,3]]
# monkey patch classes to return nil.
[NilClass, Array].each do |klass|
klass.class_eval do
def [](index)
return nil if index < 0 or index > self.size rescue nil
self.fetch(index) rescue nil
end
end
end
class Array
# calculate near values and remove nils with #compact method.
def near(i,j)
[ self[i - 1][j - 1], self[i - 1][j - 0], self[i - 1][j + 1],
self[i - 0][j - 1], self[i - 0][j + 1],
self[i + 1][j - 1], self[i + 1][j - 0], self[i + 1][j + 1],
].compact
end
end
puts big_map.near(1,1).inspect
# => [1, 2, 3, 8, 7, 1, 6, 8]
puts big_map.near(0,0).inspect
# => [2, 8, 9]
puts big_map.near(5,5).inspect
# => [2, 1, 1]
I was working on he same problem and came up with a small optimized solution to find the surrounding numbers of any point in a 2D matrix, hope this helps, please comment if I can shorten the logic somehow
Code:-
import java.util.ArrayList;
public class test {
public static void main(String[] arg){
int[][] arr = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20},{21,22,23,24,25}};
//int[][] arr = {{width,2,3},{4,5,6},{7,8,9}};
ArrayList<Integer> al = new ArrayList<Integer>();
int x = 2, y = 2;
int width = 2; //change the value of width, according to the requirement
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
if( (i == (x-width) && ( (y+width) >= j && j >= (y-width))) || (i == (x+width) && ( (y+width) >= j && j >= (y-width))) || (j == (y-width) && ( (x+width) >= i && i >= (x-width))) || (j == (y+width) && ( (x+width) >= i && i >= (x-width))) ){
//if( x >= 0 && i < (i+width) && y >= 0 && j < (j+width))
{
al.add(arr[i][j]);
}
}
}
}
System.out.println(al);
}
}
You didnt mention if you want cyclical neighbours for edges or ignores cyclical neighbours. Assuming you want cyclical neighbours here is the code,
List<Integer> getNeighbours(int[][] mat, int x, int y){
List<Integer> ret = new ArrayList<Integer>();
int rows = mat.length;
int cols = mat[0].length;
for(int i=-1,i<=1;i++)
for(int j=-1;j<=1;j++)
if(i||j) ret = ret.add(mat[(x+i)%rows][(y+j)%cols]);
return ret;
}
(x-1, y-1) -> upper left
(x-1, y) -> left
(x-1, y+1) -> lower left
(x, y+1) -> up
(x, y) -> current position
(x, y-1) -> down
(x+1, y+1) -> upper right
(x+1, y) -> right
(x+1, y-1) -> lower right
You can use this as guide. Now all you need to do is add them in a try catch.
for( int x=0; x<arr.length; x++ ){
for(int y=0; y<arr[x].length; y++){
if( arr[x][y] == 8 ){
try{
System.out.println("Upper Left is: " + arr[x-1][y-1]);
}catch(ArrayIndexOutOfBoundsException e){
//do something
}
try{
System.out.println("Left is: " + arr[x-1][y]);
}catch(ArrayIndexOutOfBoundsException e){
//do something
}
//.....and others
}
}

Java creation of a spiral [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Looping in a spiral
I'm creating a program to populate a 3 by 3 matrix. I want to result in something looking like this
5 4 3
6 1 2
7 8 9
As you have probably noticed it is a spiral.
Now the algorithm I'm using is this: I have a 2-d array where the values represent the coordinates of the number. First I assign that every number coordinate in this array will have a value of 10. Then starting at 9 I decrease my x coordinate and assign the value of the coordinate to currentnum - 1 until it reaches the end or its value is not 10; Then I do the same thing except I increase the value of Y; Then decrease the value of x; Then of Y;
The reason I assign 10 to every number is so like it acts as a road for my program. Since current num will never exceed 9. If the value of a square is 10 it is like a green light. If it is not 10 meaning a value has been assigned to that square it breaks out of it.
Here is my code, please note it is written in Java
public class spiral {
/**
* #param args
*/
public static void main(String[] args) {
int spiral [] [] = new int[3][3];
for(int i = 0; i <= 2; i++){
for(int j = 0; j <= 2; j++){
spiral[i][j] = 10;
}
}
//0 is x value, 1 is y value
spiral[0][0] = 9;
int x = 1;
int y = 1;
int counter = 1;
int currentnum = 9;
int gridsquare = 3;
for(int i = 0; i <= 8; i++){
if(counter == 5){
counter = 1;
}
if(counter == 1){
System.out.println(x + " " + y);
for(int j = 0;j <= 1;j++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
x += 1;
}
else{
y += 1;
break;
}
}
}
if(counter == 2){
for(int k = 0; k <= 0; k++){
System.out.print(x + " " + y);
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
y += 1;
}
else{
x -= 1;
break;
}
}
}
if(counter == 3){
for(int z = 0; z <= 0; z++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
x -= 1;
}
else{
y -= 1;
break;
}
}
}
if(counter == 4){
for(int b = 0; b <= 0; b++){
if(spiral[x][y] == 10){
spiral[x][y] = currentnum;
currentnum--;
y -= 1;
}
else{
x += 1;
break;
}
}
}
counter++;
}
System.out.print(currentnum);
}
}
I'm getting this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at spiral.main(spiral.java:44)
Since I'm new to Java would someone please suggest a posible fix for this. Also if you see any problems with my algorithm please do inform me.
You do not need to pre-fill with 10: zero works just as well.
I think the best approach to solving the spiral is to think of how you do it manually: start in a corner, and go horizontally until you hit non-zero or an edge of the array. Then you turn right. Stop when the current number goes past N*N.
Now let's look at what each part of the algorithm means:
Starting in the corner means setting x=0 and y=0.
Going in a straight line means x=x+dx, y=y+dy, where either dx or dy is zero, and dy or dx is 1 or -1.
Turning right means assigning dx to dy and -dy to dx.
Here is how it looks in the code:
int current = 1;
// Start in the corner
int x = 0, y = 0, dx = 1, dy = 0;
while (current <= N*N) {
// Go in a straight line
spiral[x][y] = current++;
int nx = x + dx, ny = y + dy;
// When you hit the edge...
if (nx < 0 || nx == N || ny < 0 || ny == N || spiral[nx][ny] != 0) {
// ...turn right
int t = dy;
dy = dx;
dx = -t;
}
x += dx;
y += dy;
}
You've incremented x or y to 3 which is past the end of one of your arrays.
Step through your program with the debugger or add System.out.println statements before each if (counter) to find out where you're doing this.

Is there a difference on how java performs operations using shortcut operators from the regular ones?

I am working on a java program concerning the pascal's triangle.
So this is how it is coded:
for(int i = 0; i < 5; i++){
for(int j = 0, x = 1; j <= i; j++){
System.out.print(x + " ");
x = x * (i - j) / (j + 1);
}
System.out.println();
}
and it shows:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
But when I tried to change the code to:
for(int i = 0; i < 5; i++){
for(int j = 0, x = 1; j <= i; j++){
System.out.print(x + " ");
x *= (i - j) / (j + 1);
}
System.out.println();
}
and as you may have noticed, only the operator has changed to *=, but the result is:
1
1 1
1 2 0
1 3 3 0
1 4 4 0 0
Any idea what must have happened? Thanks in advance!
It's because you're using integer arithmetic in the wrong order.
x *= (i - j) / (j + 1);
is the same as
x = x * ((i - j) / (j + 1));
The brackets are important. (i - j) / (j + 1) is in most cases not a whole number, but java rounds it to an integer anyway.
The way you did it first
x = x * (i - j) / (j + 1);
the multiplication happens before the division, so you don't get any rounding errors.
You switched the high precedence * for a low precedence *= resulting in
x = x * ((i - j) / (j + 1));
in stead of
x = (x * (i - j)) / (j + 1);
which you probably wanted.
Looks like integer division versus order of operations. Try adding some parenthesis and I think you will eventually achieve the same results. If you, say, divide 2/3 in integers, you get 0. So it matters if you do some multiplying first.

Categories