Java: Multi Dimensional array output confusion? - java

public class VarNoOfCols {
public static void main(String[] args) {
int a[][] = new int[3][];
a[0]=new int[3];
a[1]=new int[2];
a[2]=new int[1];
int temp=3;
for(int i =0; i<3;i++) {
for(int k=0;k<temp;k++) {
a[i][k]= k*10;
temp-- ;
}
}
}
}
--- output that I assumed ---- is below ---But this is incorrect.
(0 0) 0 (0 1) 10
(1 0) 0 (1 1) 10
(2 0) 0 (2,1) 10
I know this is incorrect. (My question is - on completing second iteration, "k" is greater than "temp" and when conditon fails it will stop the inner statments and do the next job (what ever it suppose to be).Why am i getting (0,2) = 20 and why i dont see (2,1) = 10 ?
You can see the correct output:
(0 0) 0 (0 1) 10 (0 2) 20
(1 0) 0 (1 1) 10
(2 0) 0
I am a learner and i really appreciate someone's help here. thank you

Change the code like that:
for(int i =0; i<3;i++)
{
for(int k=0;k<3;k++)
a[i][k]= k*10;
}
If you wanted a square output, why do you use the control variable temp that will change the number of outputted entries on each iteration over i?

this is because the temp and the k
in your program first i=0
k=0,temp=3 then (0 0) so output 0*10 = 0
k=1,temp=2 then (0 1) so output 1*10 = 10
k=2,temp=1 condition false in for loop (there the condition in the outer for loop(having i) is correct but in the inner for loop the condation k
i=1
k=0,temp=3 then (1 0) so output 0*10 = 0
k=1,temp=2 then (1 1) so output 1*10 = 10
i=2
k=0,temp=3 then (2 0) so output 0*10 = 0
k=1,temp=2 then (2 1) so output 1*10 = 10
there is no need of temp. to get correct output use this
for(int i =0; i<3;i++)
{
for(int k=0;k<3;k++)
a[i][k]= k*10;
}

Actually with your last edit (with temp-- in the second for) you obtain neither the first nor the second output.
Why?
Because you never reassign temp and after 3 time be decremented the second loop will not be executed anymore. So you got a value for (0;0) (0;1) and (1;0) only.
Why you can't obtain output 1 (square one)?
a[2] have a size of 1 so you can't have something in (2;1)
How to obtain the second output?
Don't put the temp-- in the second loop but after the second loop (at the end of the first loop).

public class VarNoOfCols {
public static void main(String[] args) {
int a[][] = new int[3][];
a[0]=new int[3];
a[1]=new int[2];
a[2]=new int[1];
int temp=3;
for(int i =0; i<3;i++)
{
for(int k=0;k<temp;k++)
//the inner for lopp doesn't have curly "{" braces.
//temp will be 3 for 1st loop and when k becomes 3 it exit inner loop.
a[i][k]= k*10;
temp--;
}
//temp--;
//System.out.println("temp : " +temp + " \n " );
}
}
Thank you guys. I figuered out the logic behind. it is not logic, it is just that { that should be watched. I will get following output if I don't use braces { in inner loop:
(0 0 ) 0 (0 1 ) 10 (0 2 ) 20
(1 0 ) 0 (1 1 ) 10
(2 0 ) 0
If the braces { and } present in inner loop with temp variable inside inner loop then I will get the following output:
(0 0 ) 0 (0 1 ) 10
(1 0 ) 0

Related

Number of ways to form an amount with certain coins

I am trying to solve this problem. http://www.lintcode.com/en/problem/coin-change-ii/#
This is the standard coin change problem solvable with dynamic programming. The goal is to find the number of ways to create an amount using an infinite set of coins, where each has a certain value. I have created the following solution :
public int change(int amount, int[] coins) {
// write your code here
int[] dp = new int[amount + 1];
dp[0] = 1;
// for(int coin : coins) {
// for(int i = 1; i <= amount; i++) {
// if(i >= coin) dp[i] += dp[i-coin];
// }
// }
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
return dp[amount];
}
Why does the first for loop give the correct answer, but the second one does not? What am I missing here? Shouldn't the answer be the same? Could you provide a visual to help me "see" why the second for loop is incorrect?
When the amount = 8 and coins = [2,3,8] the output is 5 when it should be 3 when using the 2nd for loop's technique which is not correct.
Thank you.
Let's consider the loop that works first:
for(int coin : coins) {
for(int i = 1; i <= amount; i++) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
Each iteration of the outer loop takes a coin of one value and finds out the number of ways to reach any value between the coin value and amount, adding that coin to the result of the previous iterations.
Considering your amount = 8 and coins = [2,3,8] example:
The array is initialized to
index 0 1 2 3 4 5 6 7 8
value 1 0 0 0 0 0 0 0 0
which means that without any of the coins, the only amount we can reach is 0, and we have a single way to reach that amount (0 2s, 0 3s, 0 8s).
Now we find the amounts we can reach with just the coin of value 2:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 0 1 0 1 0 1
It's not surprising that we can reach any even amount. For each such amount we have a single way to reach that amount (1 2s to reach 2, 2 2s to reach 4, etc...).
Now we find the amounts we can reach with coins of value 2 or 3. We can reach an amount k using a single coin of 3 if we already found ways to reach the amount k-3.
Below I show the number of ways to reach each value between 0 and 8, and specify how many coins of each type are used in each combination.
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 2
0x2 - 1x2 0x2 2x2 1x2 3x2 2x2 4x2
0x3 - 0x3 1x3 0x3 1x3 0x3 1x3 0x3
or or
0x2 1x2
2x3 3x3
Finally, in the last iteration we consider the coin of 8. It can only be used to reach the amount 8, so we get the final result:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 3
When you swap the loops:
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
you bring the order the coins are added into play. For example, the amount 5 can be reached by either first taking a coin of 2 and then a coin of 3, or by first taking a coin of 3 and then a coin of 5. Therefore the value of dp[5] is now 2.
Similarly, dp[8] results in 5 since you can take any of the following sequences of coins:
2+3+3
3+2+3
3+3+2
2+2+2+2
8
The original loop doesn't distinguish between 2+3+3, 3+2+3 and 3+3+2. Hence the different output.
private static int coinChange(int[] coins, int sum) {
int size = coins.length;
int[][] arr = new int[size + 1][sum + 1];
// Applying the recursive solution:
for(int i = 1; i < size +1; i++){
for(int j = 1; j < sum +1; j++) {
arr[i][0] = 1;
if (coins[i - 1] > j) {
arr[i][j] = arr[i - 1][j];
} else
arr[i][j] = arr[i - 1][j]+arr[i][j - coins[i - 1]] ;
}}
return arr[size][sum];enter code here

Why does this while loop run after the condition is met?

When I do a regular while loop like this
int x = 0;
while (x < 2) {
System.out.println(x);
x = x + 1;
}
it prints
0
1
but this second while loop runs one more time after the condition is met.
class Hobbits {
String name;
public static void main(String [] args) {
Hobbits [] which = new Hobbits[3];
int number = -1;
while (number < 2) {
number = number + 1;
which[number] = new Hobbits();
which[number].name = "bilbo";
if (number == 1) {
which[number].name = "frodo";
}
if (number == 2) {
which[number].name = "sam";
}
System.out.print(which[number].name + " is a ");
System.out.println("good Hobbit name");
}
}
}
so the result is
bilbo is a good Hobbit name
frodo is a good Hobbit name
sam is a good Hobbit name
shouldn't it stop printing at "frodo is a good Hobbit name"
I set the condition for x < 2 so how does "sam" print if the while loop was supposed to stop at x == 1?
Edit: ohhh I get it now lol I was thinking like the increment was at the end of the code and the start was 0
Here's your test case more closely matching your code:
class Test {
public static void main(String[] args) {
int x = -1;
while (x < 2) {
x = x + 1;
System.out.println(x);
}
}
}
It does indeed print:
$ java Test
0
1
2
Your loop is not designed to stop when number is 2, it's designed to stop before the next iteration if the number is 2. Since you increment number early on in the loop, it will continue with that value until it's time to choose whether to iterate again.
Before the first iteration, number = -1 which is <2 so it should iterate.
Before the second iteration, number = 0, which is <2 so iterate.
Before the third iteration, number = 1, which is <2 so iterate.
Before the fourh iteration, number = 2, which is NOT <2 so stop.
You therefore get 3 iterations.
Your original test case had the right idea -- it's better to increment as the last step in the loop. That way, you start at 0 instead of -1, and you stop the loop based on the new value rather than the previous value.
I will try to trace through it for you.
First case this is what happens.
x = 0
is 0 < 2? yes
print 0
0 <- 0 + 1 // here it becomes 1
is 1 < 2? yes
print 1
1 <- 1 + 1 // here it becomes 2
is 2 < 2? no
exit program
second loop works a bit more like this
number = -1
is number < 2? yes
number <- -1 + 1 // here it becomes 0
make hobbit "bilbo" at index 0
0 does not equal either 1 or 2
print hobbit at index 0 who is "bilbo"
is 0 < 2? yes
0 <- 0 + 1 // here it becomes 1
number equals 1 so make "frodo" at index 1
print hobbit at index 1 who is "frodo"
is 1 < 2? yes
1 <- 1 + 1 // becomes 2
number equals 2 so make "sam" at index 2
print hobbit at index 2 who is "sam"
is 2 < 2? no
end program
There's nothing wrong in that behaviour. You set number = -1 and then you do a loop that will iterate while number < 2. So, -1, 0 and 1. Three iterations. What's the problem? Let's do a simple trace:
number = -1
(-1 < 2)? Yes. Execute code inside while.
number = number + 1 (0)
(0 < 2)? Yes. Execute code inside while.
number = number + 1 (1)
(1 < 2)? Yes. Execute code inside while.
number = number + 1 (2)
(2 < 2)? No. Continue with the next instruction after the while block.
you can solve this easily with replace
int number = -1;
to
int number = 0;
Because! -1 + 1 = 0;
Because you have 3 iterations that are true:
-1 < 2 == true
0 < 2 == true
1 < 2 == true
2 < 2 == false
Cheers

Trying to properly print an array in Java

I am new to Programming so bear with me if I do not properly present my issue. I have an assignment to create a program to assign integer values 1-25 to a 25 element integer array. I need to print the array as five separate lines with each line containing 5 elements separated by commas. The last element does not have a comma following it. The final output should be as follows:
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
The code that I came up with comes close, but it's not quite right. The code that I came up with is:
public class Test2 {
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i + 1;
System.out.print(numbers[i] + ",");
if (i % 5 == 0 && i > 0)
System.out.println();
}
}
}
The printout that I get from my code is as follows:
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,
I am not sure why I am getting 1-6 on the first line as well as how to remove the comma at the end of each line. Any help pointing out my errors would be appreciated.
The error is that you are checking if int i is divisible by 5 (i % 5), not numbers[i] (numbers[i] % 5). This way, your code prints:
number 1 when i = 0,
number 2 when i = 1,
number 3 when i = 2,
number 4 when i = 3,
number 5 when i = 4,
number 6 when i = 5
and finally prints line break.
The correct code is:
int[] numbers = new int[25];
for (int i = 0; i < numbers.length; i++) {
numbers[i]=i+1;
System.out.print(numbers[i]);
if (numbers[i] % 5 == 0 && i > 0) {
System.out.println();
} else {
System.out.print(",");
}
}
The above code will print (as intended):
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
You're getting 6 numbers on the first line, because you start counting at i=0, and only print the newline once i=5; at which point the number you've just printed is 6, not 5 - you're printing i+1 in each iteration.
If you made your logic such that it printed EITHER a comma OR a newline but not both, you'd get rid of the commas at the ends of the lines.
You're close. Very close.
Consider what your condition is checking - you want to inspect a value i, and want to stop when that particular value is divisible by 5 but is nonzero.
The problem is that you have the wrong value - i isn't what you want, but numbers[i]. The reason: each number in numbers[i] is offset of i by 1.
What you want to do is check if numbers[i] is divisible by 5. You still need to check for a nonzero i, though.
if(numbers[i] % 5 == 0 && i > 0) {
System.out.println(numbers[i]);
} else {
System.out.print(numbers[i] + ",");
}
Replace
if (i % 5 == 0 && i > 0)
with
if (i % 5 == 4)

java - looping through values

I am trying to create a nested for loops that will generate all the pairs in a range specified by the user, ranging from negative values to positive values. It is a little tough to explain, but here is the code I have:
public class test method {
public static void main (String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
int c = 3;
int d = 4;
for (int i = -a; i <= a; i++)
for (int j = -b; j <= b; j++) {
System.out.println(a+" and "+b+" vs "+c+" and "+d+"\n");
}
}
}
Given command line arguments 1 and 2, my desired output would be something like:
-1 and -2 vs 3 and 4
-1 and -1 vs 3 and 4
-1 and 0 vs 3 and 4
-1 and 1 vs 3 and 4
-1 and 2 vs 3 and 4
0 and -2 vs 3 and 4
0 and -1 vs 3 and 4
0 and 0 vs 3 and 4
0 and 1 vs 3 and 4
0 and 2 vs 3 and 4
1 and -2 vs 3 and 4
1 and -1 vs 3 and 4
1 and 0 vs 3 and 4
1 and 1 vs 3 and 4
1 and 2 vs 3 and 4
I assume the lack of brackets in the first for is a problem in the copy & paste, but if that's your real code you've got a problem there.
a = Math.abs(a);
b = Math.abs(b);
for (int i = -a; i <= a; i++) {
for (int j = -b; j <= b; j++) {
System.out.println(i+" and "+j+" vs "+c+" and "+d+"\n");
}
}
Two things. First of all you should be printing i and j and second you should also consider negative values. Your for's will fail since -a if a = -1 will result in
for (int i = 1; i <= -1; i++)
The condition will not be met and the iteration won't take place. By doing Math.abs you get the absolute value of the inputs and you can do the iteration from that negative value to the positive one. If both a and b are positive the abs method will return the same values (assigning a and b with the same values they already have).
Whatever should be done with c and d remains to be seen. Your desired output says you leave them as they are so I won't touch them by now.
looks reasonable, exception for the '-a' business (and printing the wrong variables)
Assuming a/b are always positive, try
for (int i = (0-a); i <= a; i++)
for (int j = (0-b); j <= b; j++) {
System.out.println(i+" and "+j+" vs "+c+" and "+d+"\n");

How can I loop through a Sudoku board?

For example, say we have a Sudoku board like this:
0 0 6 5 8 9 7 4 3
0 5 0 0 0 0 0 6 0
7 0 9 0 6 0 1 0 0
0 3 0 0 0 2 0 8 7
0 0 1 0 0 0 4 0 0
8 9 0 6 0 0 0 5 0
0 0 2 0 5 0 3 0 6
0 7 0 0 0 0 0 9 0
3 1 8 4 9 6 5 0 0
I want to store it into one array such that the first 9 elements of the array are the first sub block, i.e. the values {0 0 6 0 5 0 7 0 9} and followed by {5 8 9 0 0 0 0 6 0}.
I've tried finding a solution but I always get an array index out of bounds error and it is too brute force. Something similar to this:
while(st.hasMoreTokens()) {
if(ctr == 27) {
c.addSubBlock(sb1);
c.addSubBlock(sb2);
c.addSubBlock(sb3);
sb1 = new SubBlock();
sb2 = new SubBlock();
sb3 = new SubBlock();
ctr = 0;
}
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
ctr+=9;
}
Please give me some tips. Code snippets would also be a great help.
EDIT: This thread somehow helped me figured it out. And yes, this is part of the Sudoku where I'm trying to encode the board into an array.
What I did was to transform first the input String into a 2d array (9x9) and use int block = (row/3)*3 + (col/3); to compute exactly which sub block each element belongs.
Create a 3x3 array of sub blocks
Use 2 counters (x & y) for tracking the position in the full board of each element read
Add the values at (x,y) into sub block (x/3,y/3)
Something like this:
SubBlock board[][] = new SubBlock[3][3];
int x, y;
for ( y=0; y<9; y++ )
for ( x=0; x<9; x++ )
board[y/3][x/3].addElement(Integer.parseInt(st.nextToken()));
board[0][0] will be the top-left SubBlock, board[2][2] the bottom-right one.
Store everything in a two dimension array. E.g.
int[] board = {
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}
{1,2,3,4,5,6,7,8,9}};
//looping
public static void Main(string[] args){
for(int i = 0; i < 9; i++)
{
System.out.println("SubBlock number"+i);
for(int j = 0; j < 9; j++){
System.out.println(board[i][j]);
}
}
}
Assuming that you are reading input left to right, top to bottom, try a set of 4 nested loops like this:
int board[] = new int[81];
for (int outY = 0; outY < 3; outY++)
{
for (int outX = 0; outX < 3; outX++)
{
for (int inY = 0; inY < 3; inY++)
{
for (int inX = 0; inX < 3; inX++)
{
board[27*outY + 9*outX + 3 * inY + inX] = //parse an int from your input here
}
}
}
}
It would be great if we knew why you are trying to loop through the board.
If you want to check if you can enter a number, I recommend you use maps for each of the 3x3 squares.
Then check if the item is in the map already or not. For the rows and columns, you can either loop over the 2D array and check each element, or -again- use a map for each column and a map for each row.
I'm not entirely sure if you want an answer for a single-dimension array or if you're willing to make it a two-dimensional array (as you mention each nine element set with curly braces), but if two-dimensional is OK...
The OP in this Code Review posting used a 'fancy' way of sifting through the subgrids by using the math (i % 3) + rowStart inside one of the square brackets and (i / 3) + colStart inside the other. One commenter noted this modulo method to be a bit obscure, and I'm prone to agree, but for how clean it is and the fact that it works, I think it's a solid solution. So, paired with the iteration of the for loop, we can sift through each 'subgrid' cell, as well as each element of row + col.
for(i=0; i<9; ++i)
{
if (puzzle[row][i] == num) return 0;
if (puzzle[i][col] == num) return 0;
if (puzzle[rowStart + (i%3)][colStart + (i/3)] == num) return 0;
}
If we find a number in one of the cells that matches, it's a duplicate, and we exit the function as 'false', or, 0.
EDIT:
Now that I think of it, you could use this same trick for a single-dimension array by using i % 9 instead of 3. You could then determine which 'row' we're on by doing i / 9 and trusting that, since we're dealing with type ints, we'll truncate the unnecessary decimals.
This does verify that this trick is a bit prone towards N-1 indexed data, as someone would assume 'go to the 81st element' would mean go to the 9th column of the 9th row, but using 81 % 9 would yield 0, and 81 / 9 would yield 9, so we'd go to the 0th place at row 9.

Categories

Resources