Im creating a program that will generate a word search game but am still in the early stages. I have taken all the input from a text file and converted it into an array that provides the word, its initial row and column starting point, and whether its horizontal or vertical. I have started a new method that will create the basic puzzle array that contains only the word to be hidden. My problem is that im consistently getting:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11
at WordSearch.createPuzzle(WordSearch.java:50)
at WordSearch.main(WordSearch.java:25)
The snippet of code that is the issue is as follows:
public static char[][] createPuzzle(int rows, int cols, Word[] words) {
char[][] puzzle = new char[rows][cols];
for (int i = 0; i <= 9; i++) {
int xcord = words[i].getRow();
int ycord = words[i].getCol();
if (words[i].isHorizontal() == true) {
String word = words[i].getWord();
for (int j = 0; j < word.length(); j++ ) {
puzzle[xcord + j][ycord] = word.charAt(j);
}
} else {
String word = words[i].getWord();
for (int k = 0; k < word.length(); k++) {
puzzle[xcord][ycord + k] = word.charAt(k);
}
}
}
return puzzle;
}
public static void displayPuzzle(String title, char[][] puzzle) {
System.out.println("" + title);
for(int i = 0; i < puzzle.length; i++) {
for(int j = 0; j < puzzle[i].length; j++) {
System.out.print(puzzle[i][j] + " ");
}
System.out.println();
}
}
with:
displayPuzzle(title, createPuzzle(11, 26, words));
in my main method alongside the code that creates the words array.
puzzle[xcord + j][ycord] = word.charAt(j);
If xcord is 8 and j is > 1 you will get an index out of bounds error because your puzzle board only has 9 rows.
You need to make sure your words don't go past the puzzle boundaries.
Related
I have two 2d boolean arrays, the smaller array (shape) is going over the larger array (world).
I am having trouble to find a method to find out when the smaller array can "fit" into the larger one.
When I run the code it either just goes through the larger array, never stopping, or stops after one step (incorrectly).
public void solve() {
ArrayList<Boolean> worldList=new ArrayList<>();
ArrayList<Boolean> shapeList=new ArrayList<>();
for (int i = 0; i < world.length; i++) {
for (int k = 0; k < world[i].length; k++) {
worldList.add(world[i][k]);
display(i, k, Orientation.ROTATE_NONE);
for (int j = 0; j < shape.length; j++) {
for (int l = 0; l < shape[j].length; l++) {
shapeList.add(shape[j][l]);
if(shapeList.equals(worldList)) {
return;
}
}
}
}
}
}
A good place to start with a problem like this is brute force for the simplest case. So, for each index in the world list, just check to see if every following index of world and shapes match.
Notice we only iterate to world.size()-shapes.size(), because naturally if shapes is longer than the portion of world we haven't checked, it won't fit.
import java.util.ArrayList;
public class Test {
ArrayList<Boolean> world = new ArrayList<>();
ArrayList<Boolean> shapes = new ArrayList<>();
public static void main(String[] args) {
new Work();
}
public Test() {
world.add(true);
world.add(false);
world.add(false);
world.add(true);
shapes.add(false);
shapes.add(true);
// Arraylists initialized to these values:
// world: T F F T
// shapes: F T
System.out.println(getFitIndex());
}
/**
* Get the index of the fit, -1 if it won't fit.
* #return
*/
public int getFitIndex() {
for (int w = 0; w <= world.size()-shapes.size(); w++) {
boolean fits = true;
for (int s = 0; s < shapes.size(); s++) {
System.out.println("Compare shapes[" + s + "] and world["+ (w+s) + "]: " +
shapes.get(s).equals(world.get(w+s)));
if (!shapes.get(s).equals(world.get(w+s))) fits = false;
}
System.out.println();
if (fits) return w;
}
return -1;
}
}
When we run this code, we get a value of 2 printed to the console, since shapes does indeed fit inside world, starting at world[2].
You can find the row and column of fitting like this
public void fit() {
int h = world.length - shape.length;
int w = world[0].length - shape[0].length;
for (int i = 0; i <= h; i++) {
for (int k = 0; k <= w; k++) {
boolean found = true;
for (int j = 0; j < shape.length && found; j++) {
for (int l = 0; l < shape[j].length && found; l++) {
if (shape[j][l] != world[i + j][k + l])
found = false;
}
}
if (found) {
//Your shape list fit the world list at starting index (i, k)
//You can for example save the i, k variable in instance variable
//Or return then as an object for further use
return;
}
}
}
I was trying to do a 2D array program to demonstrate a TRANSPOSE but I am getting error .. here is my code.
import java.util.Scanner;
/* To demonstrate TRANSPOSE USING 2-D array */
public class Array_2ddd {
public static void main(String args[]) {
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[9][9];
int myArray2[][] = new int[9][9];
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.println("Enter array from 1 to 9");
myArray1[i][j] = s1.nextInt();
System.out.print("your array is" + myArray2[i][j]);
}
}
// Transposing now...
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
System.out.print("Your array is as follow" + myArray2[i][j]);
}
}
}
}
EDIT: My error during runtime (Solved)
EDIT 2: Solved
EDIT 3: The loop is in infinity ..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity..
There are several errors in your code, also it is recommend that the dimensions of the array is to be declared as a final int, so your code works for all matrix sizes and that debugging is easier. In your original code, the errors are:
At the input step, you are printing one element of myArray[2] before you perform the transpose. That means, you are getting your array is0.
In the section commented "After transposing", you are outputting your array wrong. Namely, for each entry, you call System.out.print("Your array is as follow" + myArray2[i][j]);, and that you forgot to add a new line after each row (when inner loop is finished).
"..it keeps on asking for values fromt the user even when i wrote i<9 and j<9..it still keeps on asking for values till infinity.." There are 81 entries for the 9-by-9 case and you did not output which i,j index to be applied. You probably mistaken an infinite loop with a long but terminating loop.
Your transpose step is good.
Here is a refined version of your code which allows you to input array (in reading order, or more technically, row-major order), create a transposed array. You can copy and compare your current code with this code directly to test it.
public static void main(String args[]) {
final int m = 9; // Rows
final int n = 9; // Columns
Scanner s1 = new Scanner(System.in);
int i, j;
int myArray1[][] = new int[m][n]; // Original array, m rows n cols
int myArray2[][] = new int[n][m]; // Transposed array, n rows m cols
// Input
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
// Should be only prompt.
// Improved to show which entry will be affected.
System.out.printf("[%d][%d]" + "Enter array from 1 to 9\n", i, j);
myArray1[i][j] = s1.nextInt();
}
}
// Transposing now (watch for the ordering of m, n in loops)...
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
myArray2[i][j] = myArray1[j][i];
}
}
// After transposing, output
System.out.print("Your array is:\n");
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
System.out.print(myArray1[i][j] + " ");
}
System.out.println(); // New line after row is finished
}
System.out.print("Your transposed array is:\n");
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
System.out.print(myArray2[i][j] + " ");
}
System.out.println();
}
s1.close();
}
For an array with three rows (m = 3) and four columns (n = 4), I inputted the numbers from 0 to 9, and then 0, 1, 2. As expected, the output should be:
Your array is:
0 1 2 3
4 5 6 7
8 9 0 1
Your transposed array is:
0 4 8
1 5 9
2 6 0
3 7 1
You define your matrix as 9x9
int myArray1[][] = new int[9][9];
But actually you want to insert 10x10 items:
for (i = 0; i <= 9; i++)
{
for (j = 0; j <= 9; j++)
So either:
Redefine your arrays to store 10x10 items
int myArray1[][] = new int[10][10];
Only read and store 9x9 items in your defined array
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++)
You haven't close your first outer for loop i.e in line 17 and change your array size to 10,as you wanted take 10 input (for 0 to 9 = 10 values).
Im trying to practice some java and I am confused. I am trying to enter in multiple numbers into a 3*3 array, however when I run my program I get a compliation error (Exception in thread "main"java.lang.NumberFormatException)? How can parse multiple ints from a Joptionpane into the arrays?
public static int[][] enterMatrix() {
String NumberstoParse = JOptionPane.showInputDialog("Enter list: ");
int UserInput = Integer.parseInt(NumberstoParse);
int[][] matrix = new int[3][3];
for (int i = 0; i < matrix.length; i++)
for (int j = 0; j < matrix[i].length; j++)
matrix[i][j] = UserInput;
return matrix;
}
}
I think the main issue is when parsing the String from the JOptionPane. Integer.parseInt() sees the commas and throws NumberFormatException. Might be worthwhile to do some testing of this method, possibly with JShell!
Here, I have taken the input String "1, 2, 3, 4, 5, 6, 7, 8, 9" and used method split from class String to make an array of String that is split by (",\s+"). This means, split around the matching regular expression, which here is "a comma and one or more white space characters". Each individual String from the array is then processed with Integer.parseInt().
public static int[][] enterMatrix() {
String numberstoParse = JOptionPane.showInputDialog("Enter list: ");
String[] splitNumbers = numberstoParse.split(",\\s+");
int[][] matrix = new int[3][3];
int ctr = 0;
for (int i = 0; i < matrix.length; i++)
for (int j = 0; j < matrix[i].length; j++) {
matrix[i][j] = Integer.parseInt(splitNumbers[ctr]);
ctr++;
}
return matrix;
}
Adding to what Alex already added below is the code which will take care of some border line issues there are some test cases include few test cases. The code is documented, I hope this helps...
public class Dummy
{
public static void main(String[] args)
{
String temp = "";
for(int x = 0; x <10; x++){
temp = temp + x+"";
int[][] matrix = enterData(temp);
System.out.println("Given Input:" + temp);
if(matrix != null){
for (int i = 0; i < matrix.length; i++){
for (int j = 0; j < matrix[i].length; j++)
System.out.print(matrix[i][j] + " ");
System.out.println();
}
}
System.out.println("-------------");
temp +=",";
}
}
//Once you understand the test cases, you can remove the argument and use the JOptionPane for input
public static int[][] enterData(String input)
{
//TODO: Please user JOPtionPane I have added this just to make the test cases work
//String input = JOptionPane.showInputDialog("Enter list: ");
//This will split the Input on the basis of ","
String[] inputArr = input.split(",");
//Variable has a counter which which will represent the number of inputs received
int inputArrCount = 0;
int[][] matrix = new int[3][3];
//If the size is greater than 9, then as u suggested an error is printed
if(inputArr.length > 9 ){
System.err.println("Number length > 9");
return null;
}
for(int i = 0; i <matrix.length; i++){
for (int j = 0; j < matrix[i].length; j++){
//If to just track that inputArrCount never goes beyond the inputArr elements
if(inputArrCount < inputArr.length){
int temp = Integer.parseInt(inputArr[inputArrCount++]);
matrix[i][j] = temp;
}
}
}
return matrix;
}
}
I have a little problem that i need help with.
For this assignment (Lesson 12 HW9) name NumberFormatException,I had to do the following below
"Calculator.java, is a simple command-line calculator. Note that the program terminates if any operand is nonnumeric. Write a program with an exception handler that deals with nonnumeric operands. Your program should display a message that informs the user of the wrong operand before exiting (see the figure shown below)."
c:\exercise>java Exercise12_01 "4 + 5"
4 + 5 = 9
c:\exercise>java Exercise12_01 "4 - 5"
4 - 5 = -1
c:\exercise>java Exercise12_01 "4x - 5"
Wrong Input: 4x
SO all the math parts of the coding is finished, correct, and works, the only part I cant seem to figure out is:
" display a message that informs the user of the wrong operand before exiting" Wrong Input: 4x. I need to know what I can do to show not only the error message, but the error input as well. the part where it show the error message to the user is at the end of the code at
catch(InputMismatchException ex)
{
System.out.println("Bad input, please correct your operard.");
} //need to add the input error as well
here the full code, thank you
import java.util.*;
public class FillZerosOnes {
public static void main(String[] args) {
Scanner Read = new Scanner(System.in);
Random randNum = new Random();
int n;
int rowCount, columnCount;
int maxrowCount, maxcolumnCount;
ArrayList<Integer> Rows = new ArrayList(),Columns = new ArrayList();
int[][] matrix;
System.out.println("Enter the array size n: ");
n = Read.nextInt();
matrix = new int[n][n];
System.out.println("The random array size : ");
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
matrix[i][j] = randNum.nextInt(2);//choose the number above 1 for the number you want to be less then
//if I want 0 & 1, out 2
System.out.print(matrix[i][j]);
}
System.out.println();
}
columnCount = 0;
maxrowCount= 0;
maxcolumnCount =0;
for (int i = 0; i < n; i++)
{
rowCount =0;
for (int j = 0; j < n; j++)
{
if (matrix[i][j] ==1 )
{
rowCount++;
}
}
if (rowCount > maxrowCount )
{
maxrowCount = rowCount;
Rows.removeAll(Rows); // or Rows = new Arraylist();
Rows.add(i);
}
else if (rowCount == maxrowCount)
{
Rows.add(i);
}
}
//copy and paste
for (int j = 0; j < n; j++)
{
columnCount =0;
for (int i = 0; i < n; i++)
{
if (matrix[i][j] ==1 )
{
columnCount++;
}
}
if (columnCount > maxcolumnCount )
{
maxcolumnCount = columnCount;
Columns.removeAll(Columns); // or Rows = new Arraylist();
Columns.add(j);
}
else if (columnCount == maxcolumnCount)
{
Columns.add(j);
}
} //end paste
System.out.print("Largest row indices: ");
for (int i = 0; i < Rows.size(); i++)
{
System.out.print(Rows.get(i));
}
System.out.printf("\nLargest column indices: ");
for (int i = 0; i < Columns.size(); i++)
{
System.out.print(Columns.get(i));
}
}
}
System.out.println("text to show"+variable);
I usually log the stack trace on exception:
System.out.println("Bad input, please correct your operand." + ex.getMessage());
But you can also print out your variables in a similar manner:
System.out.println("Bad input, please correct your operands: " + n + ", " + v);
I have been wondering how to diagonally wrap, from bottom left, a String into a matrix.
For example:
String str = "123456789";
//Output matrix:
// 479
// 258
// 136
//Or if str = "123456789123456";
//Output would be:
// 2
// 73
// 484
// 2595
// 13616
Here is what I have so far:
int index = 0;
for(int i = 0; i < matrix.length; i++)
{
for(int k = matrix.length - 1; k > -1; k--)
{
if(index == word.length())
break;
matrix[k][i] = "" + str.charAt(index);
index++;
}
}
This is reasonably efficient implementation which I believe is relatively easy to understand.
This code loops over successive diagonals, and when the current position is inside the matrix, it assigns the next character from the string.
In the below chart, the question mark positions are on the diagonal but they're not inside the matrix. No character is taken from the input string for these question mark positions.
Diagonal Matrix
4 ?
3 ??
2 479
1 258?
0 136??
The loop goes through rows in ascending order, but the assignment to each row is done in reverse because your matrix is upside down when viewed from the normal Java way of indexing arrays: matrix[size - row - 1] instead of matrix[row].
There is no need for special treatment of below, at and above the diagonal this way.
public static void main(String[] args) throws Exception {
String str = "123456789";
int size = 3;
int[][] matrix = new int[size][size];
{
int index = 0;
for (int diagonal = 0; diagonal < size * 2 - 1; diagonal++) {
int row = diagonal;
int column = 0;
while (row >= 0) {
if (row < size && column < size) {
matrix[size - row - 1][column] = Character.getNumericValue(str.charAt(index++));
}
row--;
column++;
}
}
}
}
It also works for larger sized matrices (4x4, 5x5 etc.) but you can only encode values up to 9 in your string - if you want higher values, it's better to encode them in a comma-separated string and split the string into an array of strings.
Not making any claims about efficiency here, but it should work so long as your string fits into a square matrix:
static char[][] toDiag(String s)
{
int sideLen = (int) Math.sqrt(s.length()); // assume string fits into
// square matrix
char[][] m = new char[sideLen][sideLen];
int index = 0;
//fill lower-left section of array
for (int i = m[0].length - 1; i >= 0; i--)
{
for (int k = 0; k <= m[0].length-1-i; k++)
{
m[i+k][k] = s.charAt(index++);
}
}
//fill upper-right section of array
for (int i = sideLen%2==1?sideLen/2:sideLen/2 -1; i <= m[0].length; i++)
{
for (int k = 0; k <= m[0].length-1-i; k++)
{
m[k][i+k] = s.charAt(index++);
}
}
return m;
}
public static void main(String[] args)
{
String inString = "123456789";
int N = (int) Math.sqrt((double) inString.length());
int out[][] = new int[N][N];
int index=0;
//fills elements below the diagonal
for(int i=0;i<N-1;i++)
for(int j=0;j<=i;j++)
out[N-1-i+j][j] = Character.getNumericValue(inString.charAt(index++));
//fills the diagonal
for(int i=0;i<N;i++)
out[i][i] = Character.getNumericValue(inString.charAt(index++));
//fills elements above the diagonal
for(int i=N-2;i>=0;i--)
for(int j=0;j<=i;j++)
out[j][N-1-i+j] = Character.getNumericValue(inString.charAt(index++));
//prints the output
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
System.out.print(out[i][j] + "\t");
}
System.out.println();
}
}