Fill 2D array in JAVA - java

i have a file which has in it numbers that has to be inserted to 2d array but it doesn't works
here is my code
sorry for bad English
file
2,1 //starting point
3,2 //ending point
5,6 //array size which is maze
0,1,1,1,1,1 //from here till end its all gonna be inserted to 2d array
0,1,0,0,1,1 //and i somehow managed to take starting, ending point and arraysize
0,1,0,0,1,0 //all i have to do is fill the array
0,0,1,0,1,0
0,0,1,1,1,0
Complete Code
public class Mouse {
// global variables to take input from file
public static int startRow;
public static int startCol;
public static int endRow;
public static int endCol;
public static int arrayRow;
public static int arrayCol;
public static String arrayDetail;
public static void main(String[] args) throws IOException {
StringBuilder stringbuilder = new StringBuilder();
try {
BufferedReader input = new java.io.BufferedReader(new java.io.FileReader("src/input.txt"));
List<String> lines = new ArrayList<String>();
String[] stringArray = new String[lines.size()];
String line = null;
while ((line = input.readLine()) != null) {
lines = Arrays.asList(line.split("\\s*,\\s*"));
stringArray = lines.toArray(stringArray);
for (int i = 0; i < stringArray.length; i++) {
stringbuilder.append(stringArray[i]);
}
}
}
catch (FileNotFoundException e) {
System.err.println("File not found.");
}
System.out.println(stringbuilder);
//giving global variables a value that i need
startRow = Integer.parseInt(stringbuilder.substring(0, 1));
startCol = Integer.parseInt(stringbuilder.substring(1, 2));
endRow = Integer.parseInt(stringbuilder.substring(2, 3));
endCol = Integer.parseInt(stringbuilder.substring(3, 4));
arrayRow = Integer.parseInt(stringbuilder.substring(4, 5));
arrayCol = Integer.parseInt(stringbuilder.substring(5, 6));
arrayDetail = stringbuilder.substring(6);
//i cant give array values to the long variable because it's out of range
Home home = new Home();
home.print(); // print maze before releasing mouse
if (home.walk(startRow,startCol)) { //starting position
System.out.println("Ok"); //print okay if its successful
}
else {
System.out.println("No Solution"); //if unsuccessful
}
home.print(); // print maze to track how mouse went
}
}
class Home{
Home(){}
int[][] A = new int[Mouse.arrayRow][Mouse.arrayCol]; //giving array size
{
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[i].length; j++) {
for (int k = 0; k < Mouse.arrayDetail.length(); k++) {
//and its the problem doesn't take values
A[i][j] = Integer.parseInt(Mouse.arrayDetail.substring(k, k+1));
//and it gives me bunch of 000 it means its null and not taking values right ?
}
}
}
}
// road is 1
// wall is 0
// the roads that mouse went only one time is 2
// 3 is the road that mouse went but did not get success i mean the roads mouse went 2 times
public boolean walk(int row, int col) { //method to walk
boolean result = false;
if (check(row, col)){
A[row][col] = 3;
if (row == Mouse.endRow && col == Mouse.endCol) { //ending position
result = true;
}
else {
result = walk(row+1, col); //down
if(!result)
result = walk(row, col+1); //right
if(!result)
result = walk(row-1, col); //up
if(!result)
result = walk(row, col-1); //left
}
}
if (result == true) {
A[row][col] = 2;
}
return result;
}
public boolean check(int row, int col) { //check there is a road
boolean result = false;
if (row<A.length && row >=0 && col >=0 && col < A[0].length ) {
if (A[row][col] == 1) {
result = true;
}
}
return result;
}
public void print() { //method to print maze
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[i].length; j++) {
System.out.print(A[i][j]);
}
System.out.println();
}
}
}
output
000000
000000
000000
000000
000000
No Solution
000000
000000
000000
000000
000000
// It looks like your post is mostly code; please add some more details. so i am adding nonsense texts. It looks like your post is mostly code; please add some more details. so i am adding nonsense texts.

You can fill the 2d array A like this
int[][] A = new int[Mouse.arrayRow][Mouse.arrayCol]; //giving array size
{
for (int i = 0; i < A.length; i++) {
for (int j = 0; j < A[i].length; j++) {
A[i][j] = Mouse.arrayDetail.charAt(i * Mouse.arrayCol + j) - '0';
}
}
}

Related

Creating a matrix of ArrayList<byte[]> and rotating it

So I'm creating many byte[] that I would like to be placed in a matrix, eg. 3x3, so 9 byte[] which I can then by using the methods below rotate them accordingly.
// ARRAY LIST
private static void transpose(ArrayList<byte[]> m) {
for (int i = 0; i < m.size(); i++) {
for (int j = i; j < m.get(0).length; j++) {
byte x = m.get(i)[j];
m.get(i)[j] = m.get(j)[i];
m.get(j)[i] = x;
}
}
}
public static void swapRows(ArrayList<byte[]> m) {
for (int i = 0, k = m.size() - 1; i < k; ++i, --k) {
byte[] x = m.get(i);
m.set(i, m.get(k));
m.set(k, x);
}
}
public static void rotateByNinetyToLeft(ArrayList<byte[]> m) {
transpose(m);
swapRows(m);
}
public static void rotateByNinetyToRight(ArrayList<byte[]> m) {
swapRows(m);
transpose(m);
}
When I call the inserts method I want to add to the array in the correct position. So from 0,0 then 0,1 then 1,1 .... 3,3. So I created the code to do that with..
public void inserts(byte[] s){
if(x ==y){
buffer.get(x)[y]= s;
System.out.println(y);
y++;
}
else{
buffer.get(x)[y]= s;
System.out.println(x);
x++;
}
counter++;
}
But It won't allow me to execute the insertion properly. Unsure as to what is the problem.
Kind of feel like i'm making a very blatant mistake, any help would be great
thank you
EDIT:
code for array of arrays:
private static void transposeb(byte[][] m) {
for (int i = 0; i < m.length; i++) {
for (int j = i; j < m[0].length; j++) {
byte x = m[i][j];
m[i][j] = m[j][i];
m[j][i] = x;
}
}
}
public static void swapRowsb(byte[][] m) {
for (int i = 0, k = m.length - 1; i < k; ++i, --k) {
byte[] x = m[i];
m[i] = m[k];
m[k] = x;
}
}
public static void rotateByNinetyToLeftb(byte[][] m) {
transposeb(m);
swapRowsb(m);
}
public static void rotateByNinetyToRightb(byte[][] m) {
swapRowsb(m);
transposeb(m);
}
and insertion
private byte[][] buffer;
private int x=0;
private int y=0;
public FixedBuffer(int BUFF_SIZE) {
this.BUFF_SIZE = BUFF_SIZE;
buffer = new byte[BUFF_SIZE][BUFF_SIZE];
}
public void inserts(byte[] s){
if(x ==y){
buffer.get(x)[y]= s;
System.out.println(y);
y++;
}
else{
buffer.get(x)[y]= s;
System.out.println(x);
x++;
}
counter++;
}
Say we have a vector of 3 x 3
I want to use inserts() to add all the byte[], there will be 9 in total. so 9 byte[], each time I add one the index's (x and y) change.
Structure:
byte[], byte[], byte[]
byte[], byte[], byte[]
byte[], byte[], byte[]
Some test code first.
ArrayList<byte[]> arr = new ArrayList<byte[]>(9);
initialize(arr);
printRows(arr);
arr = transpose(arr);
printRows(arr);
Initialize ArrayList with random test data
private static void initialize(ArrayList<byte[]> arr) {
for(byte i = 0 ; i < 9 ; i++) {
byte[] a = {i,i,i,i};
arr.add(a);
}
}
A way to find out if all the ops are working as required.
private static void printRows(ArrayList<byte[]> arr) {
int row = 0;
for(int i = 0 ; i < arr.size() ; i++) {
System.out.print(Arrays.toString(arr.get(i)) + " ");
row++;
if(row%3 == 0)
System.out.println();
}
System.out.println("\n\n");
}
The method to transpose. Took the hacky way of making a new ArrayList. Please change that. This is just to demonstrate the logic.
private static ArrayList<byte[]> transpose(ArrayList<byte[]> arr) {
ArrayList<byte[]> newArr = new ArrayList<byte[]>(9);
// fill with null
for(int i = 0 ; i < 9 ; i++)
newArr.add(null);
for(int row = 0; row < 3 ; row++) {
for(int col = 0 ; col < 3 ; col++) {
// diagonal
if(row == col) {
newArr.add(row + 3*col, arr.get(row + 3*col));
}
int second = row + 3*col; // elem at (row,col)
int first = 3*row + col; // elem at (col,row)
// swap
newArr.set(first, arr.get(second));
newArr.set(second, arr.get(first));
}
}
return newArr;
}

IF Statement Checking (Not Working Properly)

randomEmpty() returns a random coordinate on the n x n grid that is empty (Method works). randomAdjacent() uses randomEmpty() to select an EMPTY coordinate on the map. Comparisons are then made to see if this coordinate has an VALID adjacent coordinate that is NON-EMPTY. The PROBLEM is that randomAdjacent does not always return the coordinates of space with an adjacent NON-EMPTY space. It will always return valid coordinates but not the latter. I can't spot the problem. Can someone help me identify the problem?
public int[] randomEmpty()
{
Random r = new Random();
int[] random = new int[2];
int row = r.nextInt(array.length);
int column = r.nextInt(array.length);
while(!(isEmpty(row,column)))
{
row = r.nextInt(array.length);
column = r.nextInt(array.length);
}
random[0] = row+1;
random[1] = column+1;
return random;
}
public int[] randomAdjacent()
{
int[] adjacentToX = new int[8];
int[] adjacentToY = new int[8];
int[] adjacentFrom = randomEmpty();
int count;
boolean isTrue = false;
boolean oneAdjacentNotEmpty = false;
while(!(oneAdjacentNotEmpty))
{
count = 0;
if(validIndex(adjacentFrom,1,-1))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,0,-1))
{
adjacentToX[count] = adjacentFrom[0];
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,-1,-1))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1]-1;
count++;
}
if(validIndex(adjacentFrom,-1,0))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1];
count++;
}
if(validIndex(adjacentFrom,-1,1))
{
adjacentToX[count] = adjacentFrom[0]-1;
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,0,1))
{
adjacentToX[count] = adjacentFrom[0];
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,1,1))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1]+1;
count++;
}
if(validIndex(adjacentFrom,1,0))
{
adjacentToX[count] = adjacentFrom[0]+1;
adjacentToY[count] = adjacentFrom[1];
count++;
}
for(int i = 0; i < count; i++)
{
if(!(isEmpty(adjacentToX[i],adjacentToY[i])))
{
oneAdjacentNotEmpty = true;
isTrue = true;
}
}
if(isTrue)
break;
else
adjacentFrom = randomEmpty();
}
return adjacentFrom;
}
public boolean validIndex(int[] a,int i, int j)
{
try
{
Pebble aPebble = array[a[0]+i][a[1]+j];
return true;
}
catch(ArrayIndexOutOfBoundsException e)
{
return false;
}
}
public void setCell(int xPos, int yPos, Pebble aPebble)
{
array[xPos-1][yPos-1] = aPebble;
}
public Pebble getCell(int xPos, int yPos)
{
return array[xPos-1][yPos-1];
}
JUNIT Test Performed:
#Test
public void testRandomAdjacent() {
final int size = 5;
final Board board2 = new Board(size);
board2.setCell(1, 1, Pebble.O);
board2.setCell(5, 5, Pebble.O);
int[] idx = board2.randomAdjacent();
int x = idx[0];
int y = idx[1];
boolean empty = true;
for (int i = x - 1; i <= x + 1; i++) {
for (int j = y - 1; j <= y + 1; j++) {
if ((i == x && j == y) || i < 1 || j < 1 || i > size || j > size) {
continue;
}
if (board2.getCell(i, j) != Pebble.EMPTY)
empty = false;
}
}
assertFalse(empty);// NEVER gets SET TO FALSE
assertEquals(Pebble.EMPTY, board2.getCell(x, y));
}
As for the answer: I got carried away optimizing your code for readability. I'd think it's most likely
if (board2.getCell(i, j) != Pebble.EMPTY)
empty = false;
causing the problem as getCell operates in 1-based coordinates, but i, j are in 0-based.
You should think about your logic overall. The way I see it, your code might never terminate as randomEmpty() could keep returning the same field over and over again for an undetermined period of time.
I took the liberty to recode your if-if-if cascade into utility method easier to read:
public boolean hasNonEmptyNeighbor(int[] adjacentFrom) {
for(int i = -1; i <= 1; ++i) {
for(int j = -1; j <= 1; ++j) {
if(validIndex(adjacentFrom, i, j) //Still inside the board
&& // AND
!isEmpty(adjacentFrom[0]+i //not empty
,adjacentFrom[1]+j)) {
return true;
}
}
}
return false;
}
Given my previous comment about random() being not the best of choices if you need to cover the full board, your main check (give me an empty cell with a non-empty neighbor) could be rewritten like this:
public void find() {
List<Point> foundPoints = new ArrayList<Point>();
for(int i = 0; i < Board.height; ++i) { //Assumes you have stored your height
for(int j = 0; j < Board.width; ++j) { //and your width
if(isEmpty(i, j) && hasNonEmptyNeighbor(new int[]{i,j})) {
//Found one.
foundPoints.add(new Point(i, j));
}
}
}
//If you need to return a RANDOM empty field with non-empty neighbor
//you could randomize over length of foundPoints here and select from that list.
}

Java count the size of chars in array

I have to write a program that will read a picture and then print out the number of blocks inside it.
I have to read the picture as a binary matrix of the size r × c (number of rows times number of
columns).
The blocks are groups of one or more adjacent elements with the value 1.
Blocks are built exclusively of elements with value 1
Each element with value 1 is a part of some block
Adjacent elements with value 1 belong to the same block.
We only take into account the horizontal and vertical adjacency but not diagonal.
INPUT:
In the first line of the input we have the integers r and c, separated with one space.
Then we have the r lines, where each contains s 0's and 1's.
The numbers inside the individual lines are NOT separated by spaces.
The OUTPUT only print the number of blocks in the picture.
For example:
EXAMPLE 1
INPUT:
7 5
01000
00010
00000
10000
01000
00001
00100
OUTPUT:
6
EXAMPLE 2:
INPUT:
25 20
00010000000000000000
00010000000000000000
00010000000000000100
00000000000000000100
00011111111000000100
00000000000000000100
00000000000000000100
00000000000000000100
00000000000000000100
01111111111000000100
00000000000000000100
00000000000000100100
00000000000000100100
00000000000000100100
01000000000000100000
01000000000000100000
01000000000000100000
01000000000000100000
00000000000000100000
00000000000000000000
00000000000000000000
00000000000000000000
00000000000000000000
00011111111111100000
00000000000000000000
OUTPUT:
7
THE PROBLEM:
The problem that I have is that my program only works for inputs such as in example 1.
So pictures that only consist of blocks of size 1. But it doesnt work if there are multiples 1's in a picture, such as EXAMPLE 2.
In example 2 where the output should be 7(Blocks are elements of 1.They can either be vertial or horizontal).... my programs output is 30.
I don't know how to adjust the program in a correct manner so it will give me the correct input.
Thank you for your help in advance, here is my code that I am posting bellow.
import java.util.Scanner;
class Blocks{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int rowNum=sc.nextInt();
int columnNum=sc.nextInt();
char[][] matrix = new char[rowNum][columnNum];
int nbrOfBlocks = 0;
for (int a = 0; a < rowNum; a++) {
matrix[a] = sc.next().toCharArray();
int index = 0;
while (index < matrix[a].length) {
if (matrix[a][index] == '1') {
++nbrOfBlocks;
while (index < matrix[a].length && matrix[a][index] == '1') {
++index;
}
}
++index;
}
}
System.out.println(nbrOfBlocks);
}
}
EDIT: Ok, here is a solution that will work for complex shapes
public class BlockCounter {
public static void main(String[] args) {
Board board = null;
try {
board = new Board("in3.txt");
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
System.out.println("Block count: " + board.getBlockCount());
}
}
class Board {
ArrayList<String> data = new ArrayList<>();
boolean[][] used;
int colCount = 0;
public Board(String filename) throws FileNotFoundException, IOException {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
data.add(line);
colCount = Math.max(colCount, line.length());
}
}
}
public int getBlockCount() {
used = new boolean[data.size()][colCount];
int count = 0;
for (int row = 0; row < data.size(); row++)
for (int col = 0; col < colCount; col++)
used[row][col] = peek(row, col) == '1';
for (int row = 0; row < data.size(); row++)
for (int col = 0; col < colCount; col++)
if (used[row][col]) {
fill(row, col);
count++;
}
used = null;
return count;
}
public char peek(int row, int col) {
if (row < 0 || row >= data.size() || col < 0)
return '0';
String rowData = data.get(row);
if (col >= rowData.length())
return '0';
return rowData.charAt(col);
}
public void fill(int row, int col) {
if (used[row][col]) {
used[row][col] = false;
if (row > 0 && used[row - 1][col])
fill(row - 1, col);
if (col > 0 && used[row][col - 1])
fill(row, col - 1);
if (col < colCount - 1 && used[row][col + 1])
fill(row, col + 1);
if (row < data.size() - 1 && used[row + 1][col])
fill(row + 1, col);
}
}
public int getRowCount() {
return data.size();
}
public int getColCount() {
return colCount;
}
}
Explanation:
When Board.getBlockCount() is called if creates a temporary array of booleans to work with so the original board is not messed up. Then it searches the entire board for "trues" (which correspond to '1's on the board). Every time a "true" is found, a flood fill algorithm clears the entire shape to which it is connected.
If you need more performance and less memory usage (specially stack) for larger boards, you can use another flood fill algorithm like in the example that follows. The big advantage here is that it doesn't use the stack for every pixel like the one above. It is considerably more complex though.
public class BlockCounter2 {
public static void main(String[] args) {
Board2 board = null;
try {
board = new Board2("in4.txt");
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
System.out.println("Block count: " + board.getBlockCount());
}
}
class Board2 {
ArrayList<String> data = new ArrayList<>();
boolean[][] used;
Deque<Point> pointStack = new LinkedList<>();
int colCount = 0;
public Board2(String filename) throws FileNotFoundException, IOException {
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
String line;
while ((line = br.readLine()) != null) {
data.add(line);
colCount = Math.max(colCount, line.length());
}
}
}
public int getBlockCount() {
used = new boolean[data.size()][colCount];
int count = 0;
for (int row = 0; row < data.size(); row++)
for (int col = 0; col < colCount; col++)
used[row][col] = peek(row, col) == '1';
for (int row = 0; row < data.size(); row++)
for (int col = 0; col < colCount; col++)
if (used[row][col]) {
fill(row, col);
count++;
}
used = null;
return count;
}
public char peek(int row, int col) {
if (row < 0 || row >= data.size() || col < 0)
return '0';
String rowData = data.get(row);
if (col >= rowData.length())
return '0';
return rowData.charAt(col);
}
public void fill(int row, int col) {
pointStack.push(new Point(col, row));
Point p;
while (pointStack.size() > 0) {
p = pointStack.pop();
fillRow(p.y, p.x);
}
}
private void checkRow(int row, int col, int minCol, int maxCol) {
boolean uu = false;
for (int x = col; x < maxCol; x++) {
if (!uu && used[row][x])
pointStack.add(new Point(x, row));
uu = used[row][x];
}
uu = true;
for (int x = col; x > minCol; x--) {
if (!uu && used[row][x])
pointStack.add(new Point(x, row));
uu = used[row][x];
}
}
private void fillRow(int row, int col) {
int lx, rx;
if (used[row][col]) {
for (rx = col; rx < colCount; rx++)
if (used[row][rx])
used[row][rx] = false;
else
break;
for (lx = col - 1; lx >= 0; lx--)
if (used[row][lx])
used[row][lx] = false;
else
break;
if (row > 0)
checkRow(row - 1, col, lx, rx);
if (row < data.size() - 1)
checkRow(row + 1, col, lx, rx);
}
}
public int getRowCount() {
return data.size();
}
public int getColCount() {
return colCount;
}
}
EDIT2: Both solutions were made using input from txt files in order to make the debugging and testing easier for larger arrays. If you need them to work with user input (the same you have in your code) as well, just make the following changes:
Change the main method so it will listen from user input (again):
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int rowNum=sc.nextInt();
int columnNum=sc.nextInt(); // Note columnNum is not necessary
String[] matrix = new String[rowNum]; // I hope char[][] is not a requirement
for (int a = 0; a < rowNum; a++) // Read array data from user input
matrix[a] = sc.next();
sc.close();
Board2 board = new Board2(matrix); // Call the new constructor
System.out.println("Block count: " + board.getBlockCount());
}
Add a new constructor to Board2, that takes a String[] as input:
public Board2(String[] data) {
for (String line : data) {
this.data.add(line);
colCount = Math.max(colCount, line.length());
}
}
You may remove the previous constructor Board2(String filename) if it is not useful for you but it's not necessary.
Are you searching for this:
import java.util.Scanner;
class Blocks {
public static void removeBlock(char[][] matrix, int posX, int posY) {
if(0 <= posX && posX < matrix.length
&& 0 <= posY && posY < matrix[posX].length) {
if(matrix[posX][posY] == '0') {
return;
}
matrix[posX][posY] = '0';
} else {
return;
}
removeBlock(matrix, posX - 1, posY);
removeBlock(matrix, posX + 1, posY);
removeBlock(matrix, posX, posY - 1);
removeBlock(matrix, posX, posY + 1);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// read in
char[][] matrix = new char[sc.nextInt()][sc.nextInt()];
for(int a = 0; a < matrix.length; a++) {
matrix[a] = sc.next().toCharArray();
}
// calculate number of blocks
int nrBlocks = 0;
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
if(matrix[i][j] == '1') {
// we have found a block, so increment number of blocks
nrBlocks += 1;
// remove any 1's of the block from the array, so that they each block is not counted multiple times
removeBlock(matrix, i, j);
}
}
}
System.out.println(nrBlocks);
}
}
There's a linear time (in number of cells) solution to this. If I get time, I'll add the code to this answer, but if not the Wikipedia article (see EDIT below) gives pseudo code.
The idea is to scan line-by-line, assigning an incrementing unique run numbers to each runs of 1s we see (and changing the cell content to be that unique number) If in any run, the cells immediately above in the previous line were also 1 (that is, they now have a run number), then we know that their unique-run-number and the current unique-run number form part of a single block. So record that the run-above-run-number, and the current-run-number are equivalent (but don't bother to change anything on the board)
At the end, we have a count of the runs we've seen. and a set of equivalence relationships of unique-run-numbers. For each set of equivalent-numbers (say runs 3, 5, 14 form a block), we subtract from the run count the number of runs, minus 1 (in other words, replacing the multiple runs with a single block count).
I think I have some ideas to mitigate the worst case, but they're probably not worth it.
And that's the number of blocks.
The worst case for the equivalence classes is O(size of board) though (1-wide vertical blocks, with one space between them will do this). Fortunately, the entirely-black board will need only O(height of board) - each row will get one number, which will be marked equivalent with the next row.
EDIT: There's a Stackoverflow question about this already: can counting contiguous regions in a bitmap be improved over O(r * c)?
and it turns out I've just re-invented the two-pass "Connected Component Labelling" algorithm discussed on Wikipedia

Random generator does not work

i tried to implement a method to set up a board with an array of Cell object. the method then randomly place a new string "C10" over the "---" string. My class and main is below
public class Cell {
public int addSpaces;
public Cell() {
addSpaces = 0;
}
public Cell(int x) {
addSpaces = x;
}
public String toString() {
String print;
if (addSpaces == -10)
print = "C10";
else
print = "---";
return print;
}
}
import java.util.Random;
public class ChutesAndLadders {
Cell[] board = new Cell[100]; // Set array of Cell object
Random ran = new Random();
Cell s = new Cell();
public int Chut, Ladd;
public ChutesAndLadders() {
}
public ChutesAndLadders(int numChutes, int numLadders) {
Chut = numChutes;
Ladd = numLadders;
}
public void setBoard() {
for (int i = 0; i < board.length; i++)
board[i] = new Cell(); // board now has 100 Cell with toString "---"
for (int k = 1; k <= Chut; k++) {
int RanNum = ran.nextInt(board.length); // Randomly replace the
// toString
if (board[RanNum] == board[k])
this.board[RanNum] = new Cell(-10);
else
k--;
}
}
public void printBoard() { // method to print out board
int count = 0;
for (int i = 0; i < board.length; i++) {
count++;
System.out.print("|" + board[i]);
if (count == 10) {
System.out.print("|");
System.out.println();
count = 0;
}
}
}
public static void main(String[] args) {
ChutesAndLadders cl = new ChutesAndLadders(10, 10);
cl.setBoard();
cl.printBoard();
}
}
Instead of randomly placing C10 all over the board I got this output;
|---|C10|C10|C10|C10|C10|C10|C10|C10|C10|
|C10|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|
can someone tell me what i did wrong? Thank you.
I'm not sure what your intention with this was in your for-loop:
if (board[RanNum] == board[k])
But it will cause your for-loop to, for each k, generate random numbers until it generates k, and then set that cell. So for k == 1, it will always set cell 1, cell 2 for k == 2, cell 3 for k == 3, etc.
I'm guessing you want to do something more like:
for (int k = 1; k <= Chut; k++) {
int RanNum = ran.nextInt(board.length);
if (board[RanNum].addSpaces == 0) // uninitialized
this.board[RanNum] = new Cell(-10);
else
k--;
}
EDIT:
As you probably realized from the comment + other answers, the above code is not particularly readable. Something like this should be better:
int chutCount = 0;
while (chutCount < Chut)
{
int randomNum = ran.nextInt(board.length);
if (board[randomNum].addSpaces == 0) // uninitialized
{
board[randomNum] = new Cell(-10);
chutCount++;
}
}
I'm not sure exactly what you want to achieve, but if you eliminate the if else in your inner setBoard loop then you should get random placement of C10.
Change this:
for (int k = 1; k <= Chut; k++) {
int RanNum = ran.nextInt(board.length); // Randomly replace the
// toString
if (board[RanNum] == board[k])
this.board[RanNum] = new Cell(-10);
else
k--;
}
To this:
for (int k = 1; k <= Chut; k++) {
int RanNum = ran.nextInt(board.length); // Randomly replace the
// toString
this.board[RanNum] = new Cell(-10);
}
I think you meant !=.
for (int k = 1; k <= Chut; k++) {
int ranNum = (int)(Math.random()*board.length);
if (board[ranNum] != board[k])
this.board[ranNum] = new Cell(-10);
else
k--;
}

2D array Null Pointer Exception error

public class DoubleMatrix
{
private double[][] doubMatrix;
public DoubleMatrix(int row, int col)
{
if(row > 0 && col > 0)
{
makeDoubMatrix(row,col);
}
else
{
row = 1;
col = 1;
}
}
public DoubleMatrix(double[][] tempArray)
{
if(tempArray != null)
{
for(int i = 0; i < tempArray.length-1;i++)
{
if(tempArray[i].length == tempArray[i+1].length)
{
tempArray = doubMatrix;
}
}
}
else
{
makeDoubMatrix(1,1);
}
}
public int getDim1()
{
return doubMatrix.length;
}
public int getDim2()
{
return doubMatrix[0].length;
}
private void makeDoubMatrix(int row, int col)
{
double[][] tempArray = new double[row][col];
for (int i = 0;i < row;i++)
{
for(int j = 0;j < col;j++)
{
tempArray[i][j] = Math.random() * (100);
doubMatrix[i][j] = tempArray[i][j];
}
}
}
public DoubleMatrix addMatrix(DoubleMatrix secondMatrix)
{
//this. doubMatrix = doubMatrix;
double[][] tempArray;
if(secondMatrix.doubMatrix.length == doubMatrix.length)
if(secondMatrix.doubMatrix[0].length == doubMatrix[0].length)
{
tempArray = new double[doubMatrix.length][doubMatrix[0].length];
for(int i = 0; i< secondMatrix.doubMatrix.length;i++)
for(int j = 0; j< secondMatrix.doubMatrix[i].length;j++ )
{
tempArray[i][j] = secondMatrix.doubMatrix[i][j] + doubMatrix[i][j];// add two matrices
}//end for
return new DoubleMatrix (tempArray);
}
return new DoubleMatrix(1,1);
}
public DoubleMatrix getTransposedMatrix()
{
double[][] tempArray = new double[doubMatrix.length][doubMatrix[0].length];
for(int i = 0;i < doubMatrix.length;i++)
for(int j = 0;j < doubMatrix[i].length;j++)
{
tempArray[j][i] = doubMatrix[i][j];// transposed matrix2
}//end for
return new DoubleMatrix(tempArray);
}
public DoubleMatrix multiplyingMatrix(DoubleMatrix secondMatrix)
{
double[][] tempArray = new double[secondMatrix.doubMatrix.length][doubMatrix[0].length];
//check if dimension of matrix1 equal to dimension of matrix2
if(secondMatrix.doubMatrix[0].length == doubMatrix.length)
if(doubMatrix.length == secondMatrix.doubMatrix[0].length)
{
for (int i = 0; i <secondMatrix.doubMatrix.length; i++)
{
for(int j = 0; j < doubMatrix[0].length; j++)
{
for (int k = 0; k < doubMatrix.length; k++)
{
tempArray[i][j] = tempArray[i][j] + secondMatrix.doubMatrix[i][k]*doubMatrix[k][j]; // multiply 2 matrices
}
}
}//end for
}// end if
return new DoubleMatrix(1,1);
}
public void printMatrix(String text)
{
System.out.println(text);// output string
for(int i = 0; i< doubMatrix.length;i++)
{
for(int j = 0; j< doubMatrix[i].length;j++ ) {
System.out.printf("%9.1f", doubMatrix[i][j]);// out put value for matrices
}
System.out.println();
}
}
}
public class Program3
{
public static void main(String[] args)
{
int num1 = (int) (Math.random()*(10-3+1)+3);
int num2 = (int) (Math.random()*(10-3+1)+3);
DoubleMatrix doubMatObj1 = new DoubleMatrix(num1,num2);
DoubleMatrix doubMatObj2 = new DoubleMatrix(doubMatObj1.getDim1(),doubMatObj1.getDim2());
DoubleMatrix doubMatObj3;
doubMatObj2.getDim1();
doubMatObj3 = doubMatObj1.addMatrix(doubMatObj2);
doubMatObj1.printMatrix("First Matrix Object");
doubMatObj2.printMatrix("Second Matrix Object");
doubMatObj3.printMatrix("Result of Adding Matrix Objects");
doubMatObj2 = doubMatObj2.getTransposedMatrix();
doubMatObj2.printMatrix("Result of inverting Matrix Object");
doubMatObj3 = doubMatObj1.multiplyingMatrix(doubMatObj2);
doubMatObj3.printMatrix("Result of Multiplying Matrix Objects");
}
}
Hi, I have a NullPointerException error in the last line statement of the makeDoubMatrix method as well the call makedoubMatrix in side if statement of the first constructor.
doubMatrix seems to be null when I already initialize it. How will I be able to fix this problem ?
You want to initialize the array, i.e.:
private double[][] doubMatrix = new double[size1][size2];
where size1 and size2 are arbitrary sizes. What you probably want is:
if(row > 0 && col > 0)
{
doubMatrix = new double[row][col];
makeDoubMatrix(row,col);
}
else
{
doubMatrix = new double[1][1];
makeDoubMatrix(1,1);
}
which initializes the array doubMatrix to a size of row*col if both row and col are greather than 0, and to 1*1 otherwise, then calls makeDoubMatrix with its initialized size (you could have this method call after the if-else, using doubMatrix.size and doubMatrix[0].size, but I think it's more readable now).
Change the second constructor (which takes a 2D array) using the same reasoning.
You're not initializing doubMatrix. The only line which assigns a value to doubMatrix is this commented out one:
//this. doubMatrix = doubMatrix;
(And that wouldn't help.)
Ask yourself where you think you're initializing it - where do you think you've got something like:
doubMatrix = new double[1][2];
... or an assignment copying a value from another array:
doubMatrix = someOtherVariable;
If you haven't got any statements assigning it a value, you aren't initializing it, so it will always have the default value of null.

Categories

Resources