How to declare and fullfill three-dimentional array of arrays? - java

I need help completing one task from Java book that I read. I need to create a 3-dimentional array of int that will be able to store 30 values.
It's described as cuboid containing cubes. Each cube is supposed to be a cell and they should store ints from 30 to 59. How should it look like? I try to draw it but it's pretty hard for me. Here is what I've tried.
public class cw124{
public static void main (String[]args){
int tab[][][]=new int[31][30][30];
int wypelniacz=30;
for (int i=0; i<tab.length; i++){
for (int j=0; j<tab[j].length; j++){
wypelniacz=30;
for (int k=0; k<tab[k].length; k++){
tab[i][j][k]=wypelniacz++;
}
}
}
for (int i=0; i<tab.length; i++) {
for (int j=0; j<tab[j].length; j++){
for (int k=0; k<tab[k].length; k++){
wypelniacz=30;
tab[i][j][k]=wypelniacz++;
System.out.println("Row "+i+" Cell 1 "+j+" Cell 2 "+k+" "+tab[i][j][k]);
}
}
}
}
}

Your 3D array currently has 31*30*30 = 27,900 cells. If you need a 3D array with 30 cells, you can do this:
int tab[][][]=new int[5][3][2];
This will give you a 3D array with 5*3*2 = 30 cells.
You can imagine each value in square brackets to be the length of one side of the cuboid.
The next step would be:
int counter = 30;
for(int i = 0; i < tab.length; i++)
{
for(int j = 0; j < tab[0].length; j++)
{
for(int k = 0; k < tab[0][0].length; k++)
{
tab[i][j][k] = counter;
counter++;
}
}
}
This will populate all the cells with numbers from 30 to 59.

I think the following code may help you understand the task.
You have to think of the 3 dimensions as a cube, the cube contains grids, each grid has rows which then have multiple columns)
(imagine a Rubik's cube, which has 3 layers=grids, each grid then has 3 rows and each of those rows again has 3 columns)
final int gridCount = 5;
final int rowCount = 5;
final int colsPerRow = 15;
final int[][][] cube = new int[gridCount][rowCount][colsPerRow];
for (final int[][] grid : cube) {
for (int col = 0; col < grid.length; col++) { //just to show the two different versions of 'for'
final int[] row = grid[col];
row[col] = 42+ col; //set it to whatever number
}
}

Related

How do I read through a 2D array without searching out of bounds?

I have a 2D array acting as a grid.
int grid[][] = new int[5][5];
How do I search through the grid sequentially as in (0,0), (1,0), (2,0), (3,0), (4,0) then (0,1), (1,1), (2,1) ... without getting any array out of bounds exceptions.
I'm new to programming and I just can't get my head around how to do this.
You know your lengths, now use a for loop to circle through the array.
for (int i = 0;i<5;i++){
for (int j = 0;i<5;i++){
int myInt = grid[i][j];
//do something with my int
}
}
To get the lengths at runtime you could do
int lengthX = grid.length; //length of first array
int lengthY = 0;
if ( lengthX>0){ //this avoids an IndexOutOFBoundsException if you don't know if the array is already initialized yet.
lengthY = grid[0].length; //length of "nested" array
}
and then do the for loop with lengthX and lengthY.
You will need two nested loop in order to access the two dimensions of your array:
int grid[][] = new int[5][5];
for(int i = 0; i < 5; i++ ) {
for(int j = 0; j < 5; j++ ) {
int value = grid[i][j];
}
}
Use 2 forloops like the following example:
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
System.out.println(grid[i][j]);
}
}
Also i would suggest that when initializing an array to write it like this:
int[][] grid = new int[5][5]; // note the double brackets are after int and not grid
Try this:
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
System.out.println(grid[j][i]);
}
}
This code (like the other answers) uses two for loops.
It does however add some handling of edge-cases
static int[] find(int[][] mtx, int valueToLookFor)
{
int rows = mtx.length;
if(rows == 0)
return new int[]{-1,-1};
int cols = mtx[0].length;
if(cols == 0)
return new int[]{-1, -1};
for(int r=0;r<rows;r++)
{
for(int c=0;c<cols;c++)
{
if(mtx[r][c] == valueToLookFor)
return new int[]{r,c};
}
}
return new int[]{-1,-1};
}

NxN grid with countries and each country has some population

I have to simulate a contagious disease spread where the world is of NxN countries. Initially there are going to be P people in the world and then we have to assign the people uniformly at random to each country.
The problem I am having is that how do I go about assigning a number of people to each country?
If I have an array such as
String[][] world = new String[2][2];
I have 4 countries now and I can show them as a grid using for loops.
Now world[0][0] which is a country should point to a list which has people in it.
I tried list within a list
ArrayList<ArrayList<human>> world2 = new ArrayList<ArrayList<human>>();
ArrayList<human> country1 = new ArrayList<human>();
for(int i=0; i<5; i++){
human h = new human();
country1.add(i,h);
}
world2.add(country1);
ArrayList<human> country2 = new ArrayList<human>();
human h = new human();
country2.add(h);
world2.add(country2);
for (int i=0; i<world2.size(); i++){
System.out.println(world2.get(i));
}
But how do i print it in a grid format ?
EDIT1:
String[][] world = new String[2][2];
for (int row = 0; row < world.length; row++) {
System.out.print("|");
for (int col = 0; col < world.length; col++) {
System.out.print(world[row][col] + "| ");
}
System.out.println();
}
OUTPUT:
|null| null|
|null| null|
This will loop through a 3D arraylist of Integers and print the contents of all the Integer per [row][col] of the world grid. All you have to do is supplement your Human object into wherever I have Integer.
public ArrayList<ArrayList<ArrayList<Integer>>> create3D()
{
ArrayList<ArrayList<ArrayList<Integer>>> world = new ArrayList<ArrayList<ArrayList<Integer>>>();
for (int row = 0; row < 3; row++)
{
world.add(new ArrayList<ArrayList<Integer>>());
for (int col = 0; col < 3; col++)
{
world.get(row).add(new ArrayList<Integer>());
Random rand = new Random();
int randomNum = rand.nextInt((20 - 1) + 1) + 1;
for(int humanNumber = 0; humanNumber < randomNum; humanNumber++)
world.get(row).get(col).add(humanNumber);
}
System.out.println();
}
return world;
}
public void printHumanGrid(ArrayList<ArrayList<ArrayList<Integer>>> world)
{
for (int row = 0; row < world.size(); row++)
{
for (int col = 0; col < world.get(row).size(); col++)
{
System.out.print("|");
for(int humanNumber = 0; humanNumber < world.get(row).get(col).size(); humanNumber++)
System.out.print(world.get(row).get(col).get(humanNumber) + ",");
System.out.print("|");
}
System.out.println();
}
}
So I ahve two functions, one to fill a 3D arraylist and the other to print it out. Running the following
printHumanGrid(create3D());
Outputs:
|0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,||0,1,2,3,4,5,6,7,8,9,||0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,|
|0,1,2,3,4,5,6,7,8,9,||0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,||0,1,2,3,|
|0,1,2,3,4,5,6,7,8,9,||0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,||0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,|
Each line is a row in the grid. You can now add onto it, perhaps adding functionality to format it and whatnot. Good luck!

Trouble populating 2d array

I'm trying to populate a 2d array in java for a sudoku board. The numbers come from a csv file. The issue is the code just reads the first four numbers, then restarts at 0 again for a new row. How do I stop this from happening, and get it to continue to the end of the numbers?
String[] lines = Cell.toCSV().split(",");
int[] intArray = new int[lines.length];
for (int i = 0; i < intArray.length; i++) {
intArray[i] = Integer.parseInt(lines[i]);
} //convert string to int
int[][] dataArray = new int[4][4]; //4x4 sudoku game
for (int col = 0; col < size; col++) {
for (int row = 0; row < dataArray[col].length; row++) {
dataArray[col][row] = intArray[row];
}
You need a separate counter for the original array :
int index = 0;
for (int col = 0; col < dataArray.length; col++) {
for (int row = 0; row < dataArray[col].length; row++) {
dataArray[col][row] = intArray[index++];
}
This is assuming the intArray has enough values to populate the 2D array. You should probably validate that prior to this loop.
BTW, the first dimension of a 2D array is usually considered as the row, not the column, so your loop variable names are a bit confusing.

Insert integers into 2d array

private void enterbtnActionPerformed(java.awt.event.ActionEvent evt) {
int [][] array = new int [4][4]; // my array
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array[i].length; j++)
array[i][j]= ;// use for feeding the code
}
popfield.setText(Arrays.deepToString( array ) );
}
I want to insert integers into 2d array via 2 textfields one for columns and one for rows elements via two text fields xfield and yfield
So.. For create 2D int array:
//int 2 dimensional array
int[][] array = null;
//your fields values
final int xFieldVal = 5;
final int yFieldVal = 7;
//values to fill into array
final int minArrayVal = 50;
final int maxArrayVal = 100;
//create matrix / grid with dimensions (xFieldVal x yFieldVal)
array = new int[xFieldVal][yFieldVal];
(that creates recangle xFieldVal x yFieldVal- or Y*X..)
While you have rectangle array you can acces to all value for filling eg. like that:
//random generator
Random rnd = new Random();
for (int i = 0; i < xFieldVal; i++) {
for (int j = 0; j < yFieldVal; j++) {
//generate new int in interval
array[i][j] = minArrayVal + rnd.nextInt(maxArrayVal- minArrayVal+ 1);
}
}
While you will dont have rectangle array (you can have eg. just 1st dimension fixed, and 2nd not- I mean each "row" can have difference "columns" count), you have to use that loop:
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
//printing next line
System.out.println();
}
Eg. to find min and max value, you can use that:
//set on the max possible (every value should be less than that)
int min=Integer.MAX_VALUE;
//set on the min possible (every value should be more than that)
int max=Integer.MIN_VALUE;
//iteration through 1st index (eg. iteration through rows)
for (int i = 0; i < array.length; i++) {
//iteration through 2nd index of 1st index (eg. through all columns)
for (int j = 0; j < array[i].length; j++) {
//compare and assign if array value is less than actual found min
if(min > array[i][j]){
min = array[i][j];
}
//compare and assign if array value is more than actual found max
if(max < array[i][j]){
max = array[i][j];
}
}
}
I dont think you understand what a 2D array is
think of it as a grid. you insert into a single cell at a time.
a single cell belongs to a row and a column hence has a row number and column number...like an excel work book? cell b5?
so if you want to input numbers all you gotta do is have a single textfield lets call it txt
the rest is as follows
private void enterbtnActionPerformed(java.awt.event.ActionEvent evt)
{
int [][] array = new int [4][4]; // my array
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array[i].length; j++)
array[i][j]= Integer.parseInt(txt.getText());// use for feeding the code
}
popfield.setText(Arrays.deepToString( array ) );
}

Bingo Card Game Issue With Repeating Random Integers

I have this static method created for a Bingo game.
public static void bingoCard(){
int [][]card = new int [5][5];
ArrayList<Integer> alreadyUsed = new ArrayList<Integer>();
boolean valid = false;
// First row
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][0] = tmp;
valid = false;
}
// Second row
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][1] = tmp;
valid = false;
}
// Third row
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][2] = tmp;
valid = false;
}
card[2][2] = 0; // The 3rd matrix to the left and right is a 0.
// Fourth row
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][3] = tmp;
valid = false;
}
// Fifth row
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][4] = tmp;
valid = false;
}
// Creates an array to make title
String title[] = {"B","I","N","G","O"};
for(int i = 0; i < title.length;i++){
System.out.print(title[i] + "\t");
}
System.out.println();
for(int row = 0; row < card.length; row++){
for(int col = 0; col < card[row].length; col++){
System.out.print(card[row][col] + "\t");
}
System.out.println();
}
}
In the output, this piece of code outputs to this console bingo card: http://puu.sh/487mz/939c8d7a59.png
My main issue is that repeating digits. I am interested in knowing how to get rid of the repeating digits within the 5x5 arrays. Thank you!
Second EDIT: I am also interested in having the game play by itself. Meaning, it would pull out random numbers and correspond to whether or not the digits are on the board. If the condition is met for a BINGO condition, then do something. Does anyone have suggestions in regards to this?
When I've written BINGO boards, I have made an ArrayList containing all possible unique values, then made a call to Collections.shuffle( mylist) which will randomly re-order the values. Then you can iterate over the list to populate your matrix.
Just make sure you re-shuffle for each new board you make
One solution would be to have another data structure that holds all random numbers that have been generated and added into the 2D array that represents the card.
After creating a random number you could check to see if that number already exists in the data structure. If it does then generate a different number. If it doesn't then add it to the card and the data structure.
An ArrayList would be good to use here since it has a nice contains method already written for you. Here's an example.
import java.util.ArrayList;
int [][]card = new int [5][5];
ArrayList<Integer> alreadyUsed = new ArrayList<Integer>();
boolean valid = false;
for(int row = 0; row < card.length; row++){
int tmp = 0;
while(!valid){
tmp = (int)(Math.random()*15)+1;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][0]= tmp;
valid = false;
}
Also in all of your nested for loops you never use the variable col. You could simply get rid of the inner for loop in each of these nested loops.
for(int row=0; row < card.length; row++){
for(int col=0; col < card[row].length; col++){
card[row][0]=(int)(Math.random()*15)+1;
}
}
Could be changed to
for(int row=0; row < card.length; row++){
card[row][0]=(int)(Math.random()*15)+1;
}
Also card[2][2]=0; only needs to happen once, here you're setting it multiple times. This could be changed from
for(int row=0;row<card.length;row++){
for(int col=0;col<card[row].length;col++){
card[row][2]=(int)(Math.random()*15)+31;
card[2][2]=0;
}
}
To
for(int row=0;row<card.length;row++){
card[row][2]=(int)(Math.random()*15)+31;
}
card[2][2]=0;
Don't use the random function like that - instead, fill up an array or ArrayList with all of the potential random numbers. Then randomly remove numbers from that - that will ensure that you cannot get repeated numbers, as only one of each exists.
Fill an ArrayList with numbers from 1 to N, then use a java.util.Random to pick/remove numbers (shuffle is not necessary):
ArrayList<Integer> card = new ArrayList<Integer>(N);
for (int i = 0; i < N; i++)
card.add(i + 1);
Random random = Random();
int pick = card.remove(random.nextInt(card.size()));
You could easily wrap this into a class to organize things.
Here's the way I would have implemented it.
int[][] board = new int[5][5];
ArrayList<Integer> list = new ArrayList<Integer>();
int number = 0;
int index = 0;
int increment = 1;
int col = 0;
//Run a loop until you're at your last column.
while (col < board.length) {
//Ensure uniqueness of your numbers
while (list.size() < 5) {
number = (int) (Math.random() * 15) + increment;
if (!list.contains(number))
list.add(number);
}
//Add elements to the array.
for (int i : list)
board[index++][col] = i;
//Set values for the next iteration.
index = 0;
increment += 15;
list.clear();
col++;
}
board[2][2] = 0;
//Print the board.
System.out.println("B\tI\tN\tG\tO\n");
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
System.out.print(board[i][j] + "\t");
System.out.println("");
}
Results:
B I N G O
9 29 34 59 62
8 23 44 52 64
7 16 0 53 63
1 19 33 46 71
15 17 41 58 61
Create a class which represents a bingo table. Populate an array with numbers from 0 to 99. When generating a new table, shuffle this array and pull numbers from it in order.
public class BingoBoard{
Integer[] randomNumbers;
int[][] grid = new int[5][5];
public BingoBoard(){
randomNumbers = new Integer[100];
for(int i=0;i<randomNumbers.length;i++)
randomNumbers[i] = i;
populateCard();
}
public void set(int x, int y, int value){
grid[x][y] = value;
}
public void populateCard(){
//randomize the numbers you'll pull from.
//Array.asList will be backed by randomNumbers, so this works.
Collections.shuffle(Arrays.asList(randomNumbers));
for(int x=0;x<5;x++){
for(int y=0;y<5;y++){
int num = randomNumbers[x+y*5];
set(x,y,num);
}
}
}
}
This is a very efficient way to populate your grid with random values.
you could keep a list of visited random numbers generated and check it before adding this number to the game like this
boolean[] visited = new boolean[100];
for(int i = 0; i < 100; i ++) visited[i] = false;
and inside each loop use this
for(int row=0; row < card.length; row++){
int num = (int)(Math.random()*15)+1;
if visited[num]{
row --;
continue;
}
visited[num] = true;
card[row][0] = num;
}
Its simple, just use this.
int element = 5;
List<Integer> numbers = new ArrayList<Integer>(element);
for (int i = 1; i <= element * element; i++)
numbers.add(i);
Collections.shuffle(numbers);
int[][] numArr = new int[element][element];
for (int i = 0, counter = 0; i < element; i++)
for (int j = 0; j < element; j++, counter++)
numArr[i][j] = numbers.get(counter);
for (int i = 0; i < numArr.length; i++) {
for (int j = 0; j < numArr[i].length; j++) {
System.out.printf("%-5d", numArr[i][j]);
}
System.out.println();
}

Categories

Resources