I'm trying to create a 2D array of lists for a Sudoku. Essentially 81 lists each containing possible solutions to that box in the Sudoku grid. I've tried multiple declarations so far, but whenever I try to add values to a list it returns a null pointer exception. Here is an example, simply populating each of the lists with the numbers 1-9.
List<Integer>[][] sudoku = (List<Integer>[][]) new List[9][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
for (int k = 1; k < 10; ) {
sudoku[i][j].add(k);
}
}
}
I'm not even positive a 2D array of lists is the optimal way to go about this, but I've done everything from scratch (with a relatively low knowledge of java) so far so I'd like to follow through with this method. The original code looked as follows:
List[][] sudoku = new List[9][9];
Research quickly revealed that this wouldn't cut it.
Thank you in advanced for any help!
Try this one. The general idea, create a master list and while you loop through it, create one inner list.
/* Declare your intended size. */
int mainGridSize = 81;
int innerGridSize = 9;
/* Your master grid. */
List<List<Integer>> mainList = new ArrayList<List<Integer>>(mainGridSize);
/* Your inner grid */
List<Integer> innerList = null;
/* Loop around the mastergrid */
for (int i=0; i<mainGridSize; i++) {
/* create one inner grid for each iteration of the main grid */
innerList = new ArrayList<Integer>(innerGridSize);
/* populate your inner grid */
for (int j=0; j<innerGridSize; j++)
innerList.add(j);
/* add it to your main list */
mainList.add(innerList);
}
Illustrated:
If you need to vary your grid, just change the values of the gridSize.
You cannot create array of generic lists.
You can create List of Lists:
List<List<List<Integer>>> soduko = new ArrayList<>();
And then populate it as you wish.
or use casting:
List[][] soduko = (List<IntegerNode>[][]) new LinkedList[9][9];
You have create the array of Lists but you did not initialize it. Insert this in the second line an the problem should be solved.
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++){
sudoku[i][j]=new ArrayList<Integer>();
}
}
Or to do it all in one go do it like this:
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
sudoku[i][j]= new ArrayList<Integer>();
for (int k = 1; k < 10; ) {
sudoku[i][j].add(k);
}
}
}
If you know that you need exactly 81 2D arrays, you can create 3D array:
int[][][] sudoku = new int[81][9][9];
The way you did it now would produce compilation error.
Related
I want to create dynamic matrix 2d using loop in java. My code is
class Mat {
public static void main (String[] args) throws java.lang.Exception {
List<List<Integer>> group = new ArrayList<>();
List<Integer> single = new ArrayList<>();
for (int i=0; i < 3; i++){
for (int j=0; j < 3; j++){
single.add(i);
}
group.add(single);
}
group.remove(3);
System.out.println(group);
}
}
First question, how to create dynamic matrix 2D with loop? I want an output like [[0,1,2], [0,1,2], [0,1,2]] and the matrix value saved in the variable group.
Second question, after being saved in the variable group, how about if I want to remove list (number 3) in the variable? So, output is [[0,1,2], [0,1,2]].
Thanks.
For the rest of your code creates a list List<List<Integer>> by changing
single.add(i);
to
single = new ArrayList<>(); // reset every iteration
for (int j=0; j < 3; j++) {
single.add(j); // add 0,1,2
}
how if i want remove list (number 3) in the variable?
group.remove(2); //removes the element at index 2
How can I generate a 3 by 3 box layout in Java? I can do it hardcode, but I dont know how I will implement it when I use an ArrayList. I also don't know how I will create a 2d array with the use of an Arraylist. This is how I want my code to start:
for (int i = 0; i<ArrayList.size(); i++){
some content
}
Any ideas on how to start
It is possible, with an ArrayList<ArrayList<Integer>>, or any other type than Integer.
Essentially when you look at a multi-dimensional array you have an array of arrays of a certain type. In this case, to populate the array or print 3x3 ArrayList, you would iterate through them like you would with an array:
Given an ArrayList as such: ArrayList<ArrayList<Integer>> box
for (int i = 0; i < box.size(); i++) {
for (int j = 0; j < box.get(i).size(); j++) {
System.out.print(box.get(i).get(j));
}
System.out.println();
}
This is a very simple example. You can also use forEach loops as such:
for (ArrayList<Integer> row: box) {
for (Integer cell: row) {
System.out.print(cell);
}
System.out.println();
}
Note that initializing the list is a bit trickier with multiple "dimensions":
for (int i = 0; i < 3; i++) {
box.add(new ArrayList<Integer>());
for (int j = 0; j < 3; j++) {
box.get(i).add(...);
}
}
Keep in mind that this answer uses very simple Java, there is definitely more graceful ways to do it. However, I suspect that this is probably for a homework, hence the type of answer given.
I need to have the columns organized in increasing order. Right now I have the following done but, it is sorting the rows and not columns.Any help would be nice, ive been working on this all day. Thanks.
public static double[][] sortColumns(double[][] m) {
double[][] sortedArray = new double[m.length][m.length];
for (int i = 0; i < m.length; i++) {
double[] temp = new double[m.length];
for (int j = 0; j < m.length; j++) {
temp[j] = m[j][i];
}
Arrays.sort(temp);
for (int j = 0; j < temp.length; j++) {
sortedArray[j][i] = temp[j];
}
}
return sortedArray;
}
If you change
temp[j] = m[j][i];
to
temp[j] = m[i][j];
and
sortedArray[j][i] = temp[j];
to
sortedArray[i][j] = temp[j];
then your existing algorithm will work fine. It just means you'll be copying columns to your "temporary sorting area" instead of rows.
In your current solution, you are just mistaking on indexes, just like David Wallace tells you in his answer. I propose you a different answer, enumerating the possible solutions of this problem.
You have at least 4 solutions :
instead of storing your data like you are currently doing it, use the transponate of your matrix
implement yourself an efficient sorting algorithm that takes a bi-dimensional array and the index of a column in argument
at each turn of you loop, fill an array with the current column, sort it, and copy it back (if you don't care about using some additional memory, do it). That is what you are currently trying to do
transponate your matrix, sort its lines, transponate it back (if you don't want to use too much memory, use this)
I prefer the last solution, which code is :
public static double[][] sortColumns(double[][] m) {
double[][] sortedArray = new double[m.length][m.length];
// compute the transponate of m
for (int i=0 ; i<m.length ; i++)
for (int j=0 ; j<m[i].length ; j++)
sortedArray[j][i] = m[i][j];
// sort the lines of the transponate
for (int i=0; i<sortedArray.length; i++)
Arrays.sort(sortedArray[i]);
// transponate back the result of the sorting
for (int i=0 ; i<sortedArray.length ; i++)
for (int j=i+1 ; j<sortedArray[i].length ; j++) {
double tmp = sortedArray[i][j];
sortedArray[i][j] = sortedArray[j][i];
sortedArray[j][i] = tmp;
}
return sortedArray;
}
When I look at your code I see the following line:
double[][] sortedArray = new double[m.length][m.length];
it doesn't look right to me.
you need to find length and breath of the array so i would do something like this:
length = m.length;
breath = m[0].length;
if i m not sure of all rows have same no of elements i may do that check by a for loop and initialize with the max.. wud lead to memory wastage but thats another demon to tame :)
next when we write m[x][y] x represents the rows and y represents the columns so when ur doing :
for (int j = 0; j < m.length; j++) {
temp[j] = m[j][i];
}
Arrays.sort(temp);
you are fetching all the values from a column i, assigning it to temp array and sorting the column.
hope that helps
I have got a 2d list array to which I am adding characters in a loop like below. I need to be able to sort in lexiographical order each sub container of of the 2d array. Unfortunately, Collections.sort(list) does not work in this case.
List<Character>[][] list = new LinkedList[n][n];
for (int j = 0; j < n; ++j)
{
for (int m = 0; m < 1; m++)
{
// Here is the problem
list[j][m].add(new Character('b'));
// sort the array and continue
}
}
If you want to compare a list of a lists, I suggest you to use the ColumnComparator class:
Here's the code:
public class Deck {
private Card[] cards;
public Deck() {
cards = new Card[52];
String[] ranks = {"ace","two","three","four","five","six","seven","eight","nine","ten","jack","queen","king"};
String[] suits = {"hearts","diamonds","clubs","spades"};
for(int i = 0; i < suits.length; i++) {
for(int n = 0; n < ranks.length; n++) {
cards[cards.length] = new Card(ranks[i],suits[n]);
}
}
}
}
As you can see, this loops though the two given arrays and generates a card for every combination. There are 13 ranks x 4 suits = 52 cards. I expected that on the 52nd iteration, cards.length would be 51, but the compiler says
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 52
at com.cards.Deck.<init>(Deck.java:14)
Why is that?
The issue is that cards.length is not the total number of elements used in the array; it's the total number of elements in the array, regardless of what you've stored in the array so far. Consequently, as soon as you execute the inner loop, this will try accessing the 52nd element of the array, causing the exception you've seen.
To fix this, consider instead storing a counter that will keep track of the next free index, or use some simple math to derive the position that the card should go in from its suit and value. For example, since on each iteration of the outer loop you will write ranks.length elements to the array, on iteration (i, n) you will write to array index i * ranks.length + n. Using this, you could rewrite the inner loop as
// Careful... still buggy!
for(int i = 0; i < suits.length; i++) {
for(int n = 0; n < ranks.length; n++) {
cards[i * ranks.length + n] = new Card(ranks[i],suits[n]);
}
}
Additionally, note that your access into the arrays is wrong. Right now, you're writing
new Card(ranks[i],suits[n]);
However, i ranges over suits, not values. The proper code would be
new Card(ranks[n],suits[i]);
Which gives this final implementation:
for(int i = 0; i < suits.length; i++) {
for(int n = 0; n < ranks.length; n++) {
cards[i * ranks.length + n] = new Card(ranks[n],suits[i]);
}
}
More generally, though, don't use the .length field of an array to track how many used elements there are. You'll need to store that separately. Alternatively, consider using an ArrayList, which wraps an array and tracks this for you.
Hope this helps!
cards[cards.length]
Because you're trying to use an index that doesn't exist. cards.length is 52, your array is 0 - 51.
I suspect you're trying to insert each card into that array, which means you need another counter ;)
int cardIndex = 0;
for(int i = 0; i < suits.length; i++) {
for(int n = 0; n < ranks.length; n++, cardIndex++) {
cards[cardIndex] = new Card(ranks[n],suits[i]);
}
}
EDIT: What I didn't catch is what others have mentioned - you also have the counters for ranks/suits switched in the Card constructor - fixed that too.
The index variables for ranks ranks and suits are exchanged.
(Don't damage your head with your palm.)
Consider it with renamed variables:
for(int SUIT = 0; SUIT < suits.length; SUIT++) {
for(int RANK = 0; RANK < ranks.length; RANK++) {
cards[cards.length] = new Card(ranks[SUIT],suits[RANK]);
}
}
It isn't always best to use i and n. (I would have used s and r.)
Also, consider:
Card[] cards = new Card[X];
cards[X] // will never be "in bounds", indices from [0, X-1]
Happy coding.