My code needs to multiply each row of an array by each column of the next. The user inputs the height and width and the program will randomly generate the array values. It doesn't give any errors if the arrays are equal for example (3x3)(3x3) or even if you do (3x2)(2x3). if however you enter something like (3x3)(3x2) it gives an out of bounds exception.
public class Multiply {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int width = -1;
int height = 0;
int width2 = 0;
int height2 = 0;
while (width != height2) {
while (height <= 0) {
System.out.print("Enter a height for array1: ");
height = checkInt(scan);
}
while (width <= 0) {
System.out.print("Enter a width for array1: ");
width = checkInt(scan);
}
while (height2 <= 0) {
System.out.print("Enter a height for array2: ");
height2 = checkInt(scan);
}
while (width2 <= 0) {
System.out.print("Enter a width for array2: ");
width2 = checkInt(scan);
}
if (width != height2) {
System.out
.println("Error! Dimensions of matrices not compatible. Try again.");
width = -1;
height = 0;
width2 = 0;
height2 = 0;
}
}
int array1[][] = randomMatrix(height, width);
int array2[][] = randomMatrix(height2, width2);
int product[][] = matrixMultiply(array1, array2, height, width2);
printArray(product);
}// end of main method
public static int[][] randomMatrix(int height, int width) {
int array1[][] = new int[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
array1[i][j] = (int) (-10 + Math.random() * 20);
}
}
return array1;
}// end of randomMatrix method
public static int[][] matrixMultiply(int[][] array1, int[][] array2, int height, int width) {
int[][] product = new int[height][width];
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
int prod = 0;
for (int k = 0; k < array2.length; k++) {
prod = prod + array1[i][k] * array2[k][j];
}
product[i][j] = prod;
}
}
return product;
}// end of matrixMultiply method
public static void printArray(int[][] array) {
System.out.println(" ");
System.out.println("Row Major Representation:");
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
System.out.println(" ");
System.out.println("Column Major Representation:");
for (int i = 0; i < array[1].length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.print(array[j][i] + " ");
}
System.out.println();
}
}
public static int checkInt(Scanner scan) {
int width = 0;
if (scan.hasNextInt()) {
width = scan.nextInt();
return width;
} else {
scan.next();
return 0;
}
}
}// end of public class Multiply
The value of the variable "j" (Line 82) in its final iteration is causing the Out of Bounds Exception. The error occurs for (3x3)(3x2) because in the final "j" iteration, j equals 2, making the value higher than 1 (the highest index value for j's location). Adding some logic to check for when j > the highest index will prevent the issue.
Related
The contents of the matrix starts from 1 to the product of rows and columns. The method "scan" should print out as per following:
If the row is entered 4 and column is entered 7, the contents of the matrix should look like the image provided here:
the correct matrix
So far I have tried absolutely noting because I just don't know how to make this possible. I can print in zigzag, spiral but I just have no idea about this one. Please have mercy on me and grant me an insight.
This code currently prints out in a spiral pattern.
How should I modify this "scan" method so it satisfies the aforementioned condition?
import java.util.Scanner;
import java.util.Random;
public class that {
public static void main(String[] args) {
int range;
range = 100;
Scanner scn = new Scanner(System.in);
while(true) {
int m, n;
System.out.println("Enter the number of row: ");
m = scn.nextInt();
System.out.println("Enter the number of column: ");
n = scn.nextInt();
if(m <= 0||n <= 0) break;
int[][] tab = new int[m][n];
generate(tab, range);
scan(tab);
}
scn.close();
}
static int len(int x) { return (""+x).length(); }
static void generate(int[][] tab, int range) {
// Random generation
Random rg = new Random();
for(int i=0; i<tab.length; ++i)
for(int j=0; j<tab[0].length; ++j)
tab[i][j] = rg.nextInt(2*range) - range;
}
static void scan(int[][] tab) {
int m = tab.length;
int n = tab[0].length;
int totalWidth = 0;
int num = 1;
int rowStart = m - 1, rowEnd = 0, colStart = 0, colEnd = n - 1;
// Compute column widths
int[] colw = new int[n];
for(int j=0; j<n; ++j) { // For every column look down
colw[j] = len(j); // (""+j).length();
for(int i=0; i<m; ++i) {
int w = len(tab[i][j]); //("" + tab[i][j]).length();
if(w > colw[j]) colw[j] = w;
}
totalWidth += colw[j];
}
// Printing
int ris = len(m-1); // row index size
System.out.printf("%"+ris+"s ", " ");
for(int j=0; j<n; ++j)
System.out.printf("%" + colw[j] +"d ", j);
System.out.println();
System.out.printf("%"+ris+"s+"," ");
for(int j=0; j<totalWidth+n-1; ++j)
System.out.printf("-");
System.out.println();
while (rowStart >= rowEnd && colStart <= colEnd) {
// Print leftmost column from bottom to top
if (colStart <= colEnd) {
for (int i = rowStart; i >= rowEnd; i--) {
tab[i][colStart] = num++;
}
colStart++;
}
// Print top row from right to left
if (rowStart >= rowEnd) {
for (int i = colStart; i <= colEnd; i++) {
tab[rowEnd][i] = num++;
}
rowEnd++;
}
// Print rightmost column from top to bottom
if (colStart <= colEnd) {
for (int i = rowEnd; i <= rowStart; i++) {
tab[i][colEnd] = num++;
}
colEnd--;
}
// Print bottom row from left to right
if (rowStart >= rowEnd) {
for (int i = colEnd; i >= colStart; i--) {
tab[rowStart][i] = num++;
}
rowStart--;
}
}
// Prints the matrix
for(int i=0; i<m; ++i) {
System.out.printf("%"+ris+"d|", i);
for(int j=0; j<n; ++j)
System.out.printf("%" + colw[j] +"d ", tab[i][j]);
System.out.println();
}
System.out.println();
}
}
The program below ask the user how many mines he wants to see on the field and then display the field with mines.
In next step I need to calculate how many mines are around each empty cell. And I know that I
need to check 8 cells if the cell is in the middle, 5 cells if the cell is in the side, and 3
cells if the cell is in the corner. If there are from 1 to 8 mines around the cell, I need to
output the number of mines instead of the symbol representing an empty cell.
import java.util.Scanner;
import java.util.Random;
public class Minesweeper {
char[][] minesweeper = new char[9][9];
Random randNum = new Random();
Scanner sc = new Scanner(System.in);
public Minesweeper() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
minesweeper[i][j] = '*';
}
}
}
public void printMinesweeper() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(minesweeper[i][j]);
}
System.out.println();
}
}
public void randomX() {
System.out.print("How many mines do you want on the field?: ");
int numberOfMines = sc.nextInt();
int i = 0;
while (i < numberOfMines) {
int x = randNum.nextInt(9);
int y = randNum.nextInt(9);
if (minesweeper[x][y] == '*') {
minesweeper[x][y] = 'X';
i++;
}
}
printMinesweeper();
}
}
You can do it like this:
import java.util.Random;
import java.util.Scanner;
public class Minesweeper {
public static void main(String[] args) {
Minesweeper minesweeper = new Minesweeper();
minesweeper.randomX();
minesweeper.printMinesweeper();
}
char[][] minesweeper = new char[9][9];
Random randNum = new Random();
Scanner sc = new Scanner(System.in);
public Minesweeper() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
minesweeper[i][j] = '*';
}
}
}
public void printMinesweeper() {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
System.out.print(getCharAt(i, j));
}
System.out.println();
}
}
private String getCharAt(int i, int j) {
if (mineAt(i, j)) {
return "X";
}
int minesNear = countMinesNear(i, j);
return Integer.toString(minesNear);
}
private boolean mineAt(int i, int j) {
return minesweeper[i][j] == 'X';
}
private int countMinesNear(int i, int j) {
int mines = 0;
for (int x = -1; x <= 1; x++) {//near fields in x direction
for (int y = -1; y <= 1; y++) {//near fields in y direction
if (x + i >= 0 && x + i < minesweeper.length && y + j >= 0 && y + j < minesweeper.length) {//check whether the field exists
if (minesweeper[x+i][y+j] == 'X') {//check whether the field is a mine
mines++;
}
}
}
}
return mines;
}
public void randomX() {
System.out.print("How many mines do you want on the field?: ");
int numberOfMines = sc.nextInt();
int i = 0;
while (i < numberOfMines) {
int x = randNum.nextInt(9);
int y = randNum.nextInt(9);
if (minesweeper[x][y] == '*') {
minesweeper[x][y] = 'X';
i++;
}
}
printMinesweeper();
}
}
The countMinesNear(int, int) method check whether the field near exists (to prevent index errors on the edges) and counts the mines if the fields exist.
I wrote a pinetree drawer in java. First it asks for how tall the tree and after that, asks for how many times draw it under each other and at the end it draws the tree's trunk. If the first input is <= 0 it need to stop the whole program and print a message. If the first input is good, but the second input is also <= 0 then stop the program. What is the order to make it operate? Thanks in advance!
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int height;
int stars;
int level;
System.out.println("Fenyőfarajzoló program.");
System.out.print("Kérem a magasságot: ");
height = sc.nextInt();
System.out.print("Kérem a szintek számát: ");
level = sc.nextInt();
int szelesseg = height - 1;
if (height <= 0) {
System.out.println("A magasság csak pozitív lehet.");
} else if (level <= 0) {
System.out.println("A szintek száma csak pozitív lehet.");
} else {
for (int h = 0; h < level; h++) {
stars = 1;
for (int i = 0; i < height; i++) {
for (int j = szelesseg; j > i; j--) {
System.out.print(" ");
}
for (int k = 0; k < stars; k++) {
System.out.print("*");
}
stars += 2;
System.out.println();
}
}
}
for (int talp = 1; talp <= 3; talp++) {
System.out.println(" ***");
}
}
Hello may be this can help? throw an exception to tell that you have insert negative values
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
int height;
int stars;
int level;
System.out.println("Fenyőfarajzoló program.");
System.out.print("Kérem a magasságot: ");
height = sc.nextInt();
System.out.print("Kérem a szintek számát: ");
level = sc.nextInt();
int szelesseg = height - 1;
if (height <= 0) {
System.out.println("A magasság csak pozitív lehet.");
throw new Exception("height is negative");
}
if (level <= 0) {
System.out.println("A szintek száma csak pozitív lehet.");
throw new Exception("level is negative");
}
for (int h = 0; h < level; h++) {
stars = 1;
for (int i = 0; i < height; i++){
for (int j = szelesseg; j>i; j-- )
{
System.out.print(" ");
}
for (int k = 0; k < stars; k++){
System.out.print("*");
}
stars += 2;
System.out.println();
}
}
for (int talp = 1; talp <= 3; talp++) {
System.out.println(" ***");
}
}
I have a m*n matrix where every element is unique. From a given starting point I have to move to the smallest point(up, down, left, right)and then have to do the same process again. When all other surrounding point is greater than the existing one I have to stop and print the position from start. suppose I have a matrix(5*5)
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
and starting point is (2,2) then the output will be 13,8,3,2,1.
I have solved this problem my way, But the problem is its complexity. I do not think my solution is efficient. Can anyone suggest me any better solution?
N.B: Except scanner pkg, I am not allowed to import any other pkg. Here is my code:
import java.util.Scanner;
public class DirectionArray {
public static void main(String [] args) {
Scanner in = new Scanner(System.in);
int row = in.nextInt();
int col = in.nextInt();
int[][] ara = new int[row][col];
int[] ara2 = new int[4];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
ara[i][j] = in.nextInt();
}
}
System.out.println("Give starting point(x) ");
int x= in.nextInt();
System.out.println("Give starting point(y) ");
int y= in.nextInt();
int sx=x;
int sy =y;
int [] fx={+1,-1,0,0};
int [] fy={0,0,+1,-1};
int p=0;
int l=0;
int v=0;
int r=0;
int [] result=new int[row*col] ;
int min=ara[x][y];
boolean swap=true;
for(int i=0;i<(row*col)-1;i++) {
for (int k = 0; k < 4; k++) {
int nx = x + fx[k];
int ny = y + fy[k];
if (nx >= 0 && nx < row && ny >= 0 && ny < col) {
if (min > ara[nx][ny]) {
ara2[p] = ara[nx][ny];
p++;
}
}
}
p=0;
while(swap) {
swap=false;
r++;
for (int q = 0; q < ara2.length-r; q++) {
if(ara2[q]>ara2[q+1]){
int temp = ara2[q];
ara2[q]=ara2[q+1];
ara2[q+1]=temp;
swap=true;
}
}
}
for(int j=0;j<ara2.length;j++) {
if(ara2[j]!=0)
{
v=ara2[j];
result[l]=v;
l++;
break;
}
}
min=v;
for(int o=0;o<ara2.length;o++) {
ara2[o]=0;
}
for(int m=0;m<row;m++){
for(int n=0;n<col;n++){
if(ara[m][n]==v) {
x = m;
y = n;
}
}
}
I think you need to split up your code in more methods. It would make it easier to read.
For example this is how I would reorganize it:
private static final int[][] COORDINATES_TO_TRY = new int[][]{{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int row = in.nextInt();
int col = in.nextInt();
int[][] array = new int[row][col];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
array[i][j] = in.nextInt();
}
}
System.out.println("Give starting point(x) ");
int x = in.nextInt();
System.out.println("Give starting point(y) ");
int y = in.nextInt();
findMinimum(array, x, y);
return;
}
private static int[] findMinimum(int[][] array, int x, int y) {
for (int i = 0; true; i++) {
if (i > 0) {
System.out.print(",");
}
System.out.print(array[x][y]);
int[] coordinates = findLocalMinimum(array, x, y);
if (x == coordinates[0] && y == coordinates[1]) {
return coordinates;
}
x = coordinates[0];
y = coordinates[1];
}
}
private static int[] findLocalMinimum(int[][] array, int x, int y) {
int min = array[x][y];
int minX = x;
int minY = y;
for (int[] coordinates : COORDINATES_TO_TRY) {
int i = x + coordinates[0];
int j = y + coordinates[1];
if (i >= 0 && i < array.length && j >= 0 && j < array[i].length) {
if (array[i][j] < min) {
minX = i;
minY = j;
min = array[i][j];
}
}
}
return new int[]{minX, minY};
}
Well firstly, I'll show my code:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = 0;
int b = 0;
System.out.println("Welcome to Mine Sweeper!");
a = promptUser(in, "What width of map would you like (3 - 20):", 3, 20);
b = promptUser(in, "What height of map would you like (3 - 20):", 3, 20);
char[][] map = new char[a][b];
eraseMap(new char[a][b]);
}
public static int promptUser(Scanner in, String prompt, int min, int max) {
int userInput;
System.out.println(prompt);
userInput = in.nextInt();
while (userInput < min || userInput > max) {
System.out.println("Expected a number from 3 to 20.");
userInput = in.nextInt();
}
return userInput;
}
public static void eraseMap(char[][] map) {
for (int i = 0; i < map.length; ++i) {
for (int j = 0; j < map.length; ++j) {
System.out.print(Config.UNSWEPT + " ");
}
System.out.println();
}
return;
}
Basically, I'm trying to create a simple minesweeper game but what this is doing is that it is not printing the game map only using the width, instead of the width + height. For example, if I input 3 as the width and 4 as the height, it would output:
. . .
. . .
. . .
How would I fix this?
Change
for (int j = 0; j < map.length; ++j) {
to
for (int j = 0; j < map[i].length; ++j) {
because i is the outer array map[i] is the inner one. Alternatively, since you don't access map, pass in width and height instead. Like,
public static void eraseMap(int width, int height) {
for (int i = 0; i < width; ++i) {
for (int j = 0; j < height; ++j) {
System.out.print(Config.UNSWEPT + " ");
}
System.out.println();
}
}
Instead of map.length, you can use map[i].length in your inner loop.