I need to loop through a 2d array backwards for a little map project I'm doing. I tried doing so based off of what I've read online, but my 2d array is different. How can I loop through this backwards?
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length; j++) {
switch (nmap[j][i]) {
map[i][j] = new Tile();
}
}
}
To go the other way, you need to start the index at the highest value and decrease it for each iteration. Like this:
for (int i = map.length - 1; i >= 0; i--)
for (int j = map[i].length - 1; j >= 0; j--) {
switch (map[i][j]) {
map[i][j] = new Title();
}
}
Note that in both loops, we are starting from the highest index, map.length - 1 in the first and map[i].length in the second, and going down by one for each iteration until we reach the lowest index, 0 for both loops.
With for(int i = 0; i < length; i++), you're starting at the start (0), and going to the end (length).
To go the other way, just reverse everything:
for(int i = length - 1; i >= 0; i--)
Few things to note:
We have to do length - 1, or we'll start 1 past the end
We're using >= to include 0
We're decrementing i instead of incrementing it.
If you need it for a 2D array, just add a second of the above for the second dimension.
To go backwards , you need to read from the highest index to 0 . Highest index is typically length-1 since indices start from 0. Same goes for the inner j loop. Start from the highest index of map[i] i.e length -1.
eg. Array = [2 ,3,4,5,6]
Length =5 .Indices to iterate = 4 to 0 if backwards.
for(int i = map.length-1; i >= 0; i--) {
for(int j = map[i].length-1; j >= 0; j--) {
//your operation
}
}
Here you go.
for(int i = map.length-1; i >= 0; i--){
for(int j = map[i].length-1; j >= 0; j--) {
switch (nmap[j][i]) {
map[i][j] = new Tile()
}
}
}
Rather then going from 0 to map.length and 0 to map[i].length, this program starts at map.length-1 (so you don't ever get an index out of bounds error) and continues until it hits zero.
Related
I have an array of size 4 and I want to check if the array contains the number 8 (which it obviously does not, the code is just for testing).
In the for-loop j goes from 0 to 3, so the final value of j in the loop is 3. However I don't follow why the value of j after the loop has been changed to 4, why is it still not 3?
public class Test {
public static void main (String[] args) {
int[] a = new int[4];
a[0] = 2;
a[1] = 3;
a[2] = 4;
a[3] = 5;
int n = a.length; // n = 4
int number = 8;
int j;
for (j = 0; j < n; j++) {
if (a[j] == number) {
System.out.println("The number is at place " + j);
break;
}
// Last value of j is 3:
System.out.println("Value of j after each iteration " + j);
}
// But here j is 4?
System.out.println("Value of j after the for-loop: " + j);
}
}
The output:
Value of j after each iteration 0
Value of j after each iteration 1
Value of j after each iteration 2
Value of j after each iteration 3
Value of j after the for-loop: 4
Yes because at the end of a for loop there is an increment to the variable. A for loop can be rewritten as:
int j = 0;
while(j < n) {
//code
j++;
}
So on the last iteration j will be incremented, it will go to the condition, and it will be false so the body of the for loop will not be entered. In order for the loop to end, j has to be more than or equal to the condition.
Think about it...
This is your for loop:
for (j = 0; j < n; j++){
//your code here
}
You start your for loop with j = 0 and every time you iterate through it, you have to check if the value is less than n ( j < n ).
To achieve that you have to increment it on every iteration.
So this is what happens for n = 4:
1st iteration:
j = 0;
0 < 4 == true;
// you execute your code
j++; //As you can see you increment before you continue to the next iteration
2nd iteration:
j = 1; // j now equals 1 because you incremented it on the previous iteration
1 < 4 == true;
// you execute your code
j++;
3rd iteration:
j = 2;
2 < 4 == true;
// you execute your code
j++;
4th iteration:
j = 3;
3 < 4 == true;
// you execute your code
j++;
5th iteration:
j = 4;
4 < 4 == false;
// loop ends
As you can see, when your code is about to start the fifth iteration, the j variable now equals 4 so it doesn't pass the j < n criteria.
However, it still incremented in the 4th iteration so you get j = 4.
This was how my teacher explained it to me when I was just starting my coding education, I hope it helps you as it helped me!
New to programming?
for(initialization; booleanExpression; updateStatement) {
; // Body
}
The steps is,
Initialization statement executes
If booleanExpression is true continue, else exit loop
Body executes
Execute updateStatements
Return to Step 2
So the end value should be 4
The sum is -9 but i'm having trouble figuring out why. I don't understand how the j-- in the for loop will increment. It should be incremented after the body is executed, right? But doesn't the initialization of the for loop make j-- pointless? So I assume that on the 2nd iteration j becomes 2 because of i++. Could someone help look at this the right way?
public static void whatsTheSum(){
int sum = 1;
int i = 1;
while(i < 5){
for(int j = i; j > 0; j--)
sum += (j - i);
i++;
}
System.out.println(sum);
}
I don't understand how the j-- in the for loop will increment. It should be incremented after the body is executed, right?
It's updated, then, yes. (The update is a decrement, not an increment.) But yes, it happens after each time the loop body is run.
But doesn't the initialization of the for loop make j-- pointless?
No. The initialization has j start with the value from i, and then count down while j is > 0 (without changing i).
So I assume that on the 2nd iteration j becomes 2 because of i++.
The second iteration of the while loop, yes. j will start out at 2 and then the for loop will run twice (for j = 2 and j = 1).
Just for complete clarity, here's how a for loop works:
for (initialization; test; update) {
body;
}
That's executed in this order:
Do initialization
Evaluate test, if false leave the loop
Do body
Do update
Jump to Step 2
To what I understand the requirement stated in the question above to increment j to iterate from 0 to i, you would require something like -
while(i < 5){
for(int j = 0; j < i; j++) {
sum += (j - i);
}
i++;
}
also j++ can be replaced as j=j+1 , j += 1 they would have eht esame effect and the order is very nicely explained by #T.J's answer.
So if you have nested loops its always good to write down each and every iteration:
i = 1, sum = 1
1. while (i < 5) = true so
1.1 for(int j = 1; j > 0; j--) j=1
sum += (1-1)
i=2 sum =1
2. while (i < 5) = true so
2.1 for(int j = 2; j > 0; j--)
sum += (2-2) --> sum = 1
2.2 for(int j = 1; j > 0; j--)
sum += (1-2) --> sum = 0
i=3 sum =0
3. while (i < 5) = true so
3.1 for(int j = 3; j > 0; j--)
sum += (3-3) --> sum = 0
3.2 for(int j = 2; j > 0; j--)
sum += (2-3) --> sum = -1
3.3 for(int j = 1; j > 0; j--)
sum += (1-3) --> sum = -3
And so on
for(int i =0; i <= 1; i++)
{
for(int j =0; j <= i; j++)
{
System.out.print(i);
}
}
Output: 011
I just want to know how this happened.
You have two loops:
for(int i =0; i <= 1; i++) //external loop
for(int j =0; j <= i; j++) //internal loop
System.out.print(i);
The external loop has 2 iteration since it starts in i = 0 and ends in i = 1 when i is incremented to i = 2 you exit the for loop.
The internal loop has i + 1 iterations.
When i = 0 the internal loop iterates once. That`s when you get the 0.
When i = 1 the internal loop iterates twice (j = 0 and j = 1). That`s when you get 11
I'm a beginner to Java and can't figure out how to print an upside down triangle of numbers. The numbers should decrease in value by 1 for each row. Ex. Number of rows: 6;
Print:
666666
55555
4444
333
22
1
So far this is what I came up with; (int nr is scanned input from user)
for (int i = 1; i <= nr; i++) {
for (int j = 1; j <= nr; j++) {
System.out.print(nr);
}
nr--;
System.out.println();
}
By having nr--; the loop gets shorter and I cant figure out how to keep the loop going for nr-times, yet still decreasing the amount of numbers printed out.
You are right in that you need to write a loop to print a line for each number, starting at nr and decreasing by 1 until you get to 0. But you also have to print a variable number of numbers at each line. To do that, a nested loop could be used to print the number the amount of times necessary.
Since you start printing at nr and decrease until you reach 1, you could try writing an outer loop that decrements rather than increments. Then use a nested loop to print the number the required number of times. For example:
for (int i = nr; i > 0; i--) {
for (int j = 0; j < i; j++) {
System.out.print(i);
}
System.out.println();
}
In this case, you can use a single while loop and two decreasing variables:
i - number of the row - from 6 to 1
j - number of repetitions in the row - from i to 1:
int i = 6, j = i;
while (i > 0) {
if (j > 0) {
// print 'i' element 'j' times
System.out.print(i);
--j;
} else {
// start new line
System.out.println();
j = --i;
}
}
Output:
666666
55555
4444
333
22
1
See also: Printing a squares triangle. How to mirror numbers?
You can't decrease nr and still use it as upper limit in the loops. You should in fact consider nr to be immutable.
Instead, change outer loop to count from nr down to 1, and inner loop to count from 1 to i, and print value of i.
for (int i = nr; i > 0; i--) {
for (int j = 0; j < i; j++) {
System.out.print(i);
}
System.out.println();
}
Your problem is that you are changing nr, try:
int original_nr = nr;
for (int i = 1; i <= original_nr; i++) {
for (int j = 1; j <= nr; j++) {
System.out.print(nr);
}
nr--;
System.out.println();
}
I had to write a method in Java, where having in input an array a of numbers and a number x returns an array of elements which follows the last occurrence of x in a.
For example with input {0,1,2,3,4,5,6,7,8,9} and x=6 the method must return {7,8,9} meanwhile with {4,1,4,2} and x=4 the method must return {2} and if the x is not in a then it must return empty array {} (or array with 0 length)
so I got this answer:
int idx = -1;
for (int i = 0; i < s.length; i++) {
if (s[i] == x)
idx = i;
}
/* After you found this index, create a new array starting
* from this element. It can be done with a second (not nested) for loop, or you can
* use Arrays.copyOfRange()
*/
//make sure idx != -1
int[] t = new int[s.length - idx - 1];
for (int i = idx + 1; i < s.length; i++)
t[i - idx - 1] = s[i];
which was very helpful but I could not understand why this works:(EDITED; Ok now I understand why this works but even if in my opinion the combined for loop ideea was more less complicated to read)
t[i - idx - 1] = s[i];
and this doesn't:
int[] t = new int[a.length - indx - 1];
for (int j = indx + 1; j < a.length; j++) {
for (int i = 0; i < t.length; i++) {
t[i]=a[j];
}
}
return t;
EDITED :
To clarify this is all the code
int[] dopoX(int[] a, int x) {
int n = a.length;
int[] c = new int[0];
int indx = 0;
int nrx = 0;
for (int j = 0; j < a.length; j++) {
if (a[j] == x)
nrx++;
if (a[j] == x)
indx=j;
}
if (nrx == 0)
return c;
int[] t = new int[n - indx - 1];
for (int j = indx + 1; j < n; j++) {
for (int i = 0; i < t.length; i++) {
t[i] = a[j]; /* it returns just 1 number of a[] like t{2,2,2,2,2,2,2,2} which is
not correct */
}
}
return t;
}
Well you want to copy all the remaining values, and create an array of index t. Thus you need to start with i=0. You can however perform a shift-operation: increase i somewhere, and when you use it, shift it back, so:
for (int i = idx+1; i < s.length; i++)
t[i-idx-1] = s[i];
is equvalent to:
for (int i = 0; i < t.length; i++)
t[i] = s[i+idx+1];
(which would have been more readable as well)
About your second question:
here you use a nested loop: the second for loop will be repeated each iteration of the first one.
The result is thus that in the second for-loop, j is always fixed, with input {1,2,...,9} and 6 in the first iteration, you would fill your array with 7s, next 8s and finally 9s.
You can however use a combined for loop:
int []t=new int[n-indx-1];
// /-- grouped initializers /-- grouped increments
// | |
for(int i=0, j= indx+1; i < t.length; i++, j++){
t[i]=a[j];
}
return t;
Let's suppose you take the case where a[] = {1,2,3,4,5,6,7,8,9} and x = 6.
Running this:
int idx = -1;
for (int i = 0; i < s.length; i++) {
if (s[i] == x) idx = i;
}
You got idx = 5 as s[5] == x.
Now we want to copy the array after the last instance of x into a new array t[].
Obviously, you have to start from the index idx + 1 as idx contained the last occurance of x.
Hence, this code:
int[] t = new int[s.length - idx - 1];
for (int i = idx+1; i < s.length; i++)
t[i-idx-1] = s[i];
What do you do here?
You construct a new array t[] having length s.length - idx - 1, in our case s.length = 9 and idx = 5 hence, we have the s.length - idx - 1 as 3 and we can check that is the number of elements after x = 6.
Now, we start the iterator i from idx + 1 (Reason explained above) to s.length
We have t[i - idx - 1] because when i = idx + 1, i - idx - 1 = 0. Hence as i increases, your i - idx - 1 also increases.
Hope it was convincing. Please comment if you still have any doubts.
The first line of code finds the last index of x inside of the array.
The second line uses the built-in function of Arrays to copy a range from an array to a new copy.
And we copy from the values after the last x until lenght of array a.
The first line could be rewritten to search from the end and backwards in the array with a break. This will give a performance boost but makes the code less easy to read.
for(int i=0; i<a.length;i++) if(a[i]==x) idx=i;
int[] b = Arrays.copyRangeTo(a, idx+1, a.length);
Try this:
int j=0;
int i=idx+1;
while (j<t.length) {
t[j] = s[i];
j++;
i++;
}