Create and fill grid using 2D array and user input - java

I created a program which asks the User to specify the width, height and characters for a grid. However, when it prints the grid, it is all on one line and not 2D.
public static void main(String[] args) {
System.out.println("A B C - create a new grid with Width A, Height B and Character C to fill grid);
Scanner scan = new Scanner(System.in);
int Width = scan.nextInt();
int Height = scan.nextInt();
char C = scan.next().charAt(0);
char [][] grid = new char [Width][Height];
for (int row = 0; row < Width-1 ; row++) {
for (int col = 0; col < Height-1; col++) {
grid[row][col] = C;
System.out.print(grid[row][col]);
}
}
}

You need to print a new line '\n' character after each line. Otherwise the console will not know when a row has finished.
Also you didn't name your variables correctly. The outer loop should iterate over your rows and go from 0 to height - 1 and the inner (columns) should go from 0 to width - 1. If this is confusing, think of another common way of indexing pixels: x and y. while x denotes in which column you are, why y denotes in which row you are.
int width = scan.nextInt();
int height = scan.nextInt();
char c = scan.next().charAt(0);
char [][] grid = new char [width][height];
for (int row = 0; row < height - 1; col++) {
for (int col = 0; col < width - 1; row++) {
grid[col][row] = c;
System.out.print(grid[col][row]);
}
System.out.print("\n");
}
In addition please note that I took the liberty and named your variables with lower letters (height and width) to bring them in line with the java naming conventions.

Related

Dropping characters when printing from 2D array

I have a string of characters for which I want to encrypt by loading into a 2D array by rows and then printing the array by column. Such that:
|A|B|
|C|D|
|E|
encrypts to "ACEBD".
However I cant seem to be able to avoid dropping characters in the last row in my output getting "ACBD". Any idea how to solve this?
public static void main(String[] args) throws FileNotFoundException {
if (handleArguments(args))
System.out.println("encrypt");
// get input
Scanner input = new Scanner(inputFile);
String line = input.nextLine();
// calculate height of the array
int height = line.length() / width;
// Add one to height if there's a partial last row
if (line.length() % width != 0)
height += 1;
loadUnloadGrid(line, width, height);
}
static void loadUnloadGrid(String line, int width, int height) {
// make an empty array
char grid[][] = new char[height][width];
// fill the array row by row with character from line
int charCount = 0;
for (int r = 0; r < height - 1; r++) {
for (int c = 0; c < width; c++) {
// check to make sure accessing past end of the line
if (charCount < line.length()) {
grid[r][c] = line.charAt(charCount);
charCount++;
}
}
}
// print to standard output the characters in array
System.out.printf("Grid width %d: \"", width);
for (int r = 0; r < width; r++) {
for (int c = 0; c < height; c++) {
System.out.print(grid[c][r]);
}
}
// !!Special handling for last row!!
int longColumn = line.length() % width;
if (longColumn == 0)
longColumn = width;
for (int c = 0; c < longColumn; c++) {
System.out.print(grid[height - 1][c]);
}
System.out.println();
}
You need to loop the rows before you loop the columns, i.e., just the way you usually don't do it.
for (int i = 0; i < array[0].length; i++) {
for (int j = 0; j < array.length; j++) {
// prints columns before rows
}
}
However, be aware that you cannot check whether one row has less columns than another within the loop. Usually array[i].length avoids any NPEs. In this case you might want to define a check whether the array at row j even has column i. This could be done within the second loop by checking:
if (array[j].length > i)
// System.out.println(...);
else
break;
Edit: I see your loop should be working correctly. Most likely height is only 1 instead of 2 and thus, the last row gets cut off. My code as it is works for your input and your loop should be working the same way. Try to print height and check if it is correct or debug your program and go through it step by step.

How to take input while printing mirror image if mirror is placed along one of the sides of the array

Given a two dimensional array, print its mirror image if mirror is placed along one of the sides of the array.
Input
First line of input will contain a number T = number of test cases. Each test case will contain two positive integers n and m (1<=n, m<=50) on a single line separated by space. Next n lines will each contain a string of exactly m characters. Next line will contain a character 'V' or 'H'. If character is V, mirror is placed vertically along the right-most column. If the character is H, the mirror is placed horizontally along the bottom-most row.
Output
For each test case, print the n*m mirror image - n lines with strings of m character each. Print an extra empty line after output for each test case.
Sample Input
2
3 3
abc
def
ghi
V
3 4
1234
5678
9876
H
Sample Output
cba
fed
ihg
9876
5678
1234
MyApproach:
When I wrote the following Code.I am having problem while taking input.
How to stop taking the input when the length of the input become equal to m characters.
Below is the code
int arr[][]=new int[n][m];
for(int j=0;j<n;j++)
{
for(int k=0;k<m;k++)
{
arr[j][k]=sc.nextInt();
//but if the input is in character how can i stop
//I think I need to read the characters character by character and stop hen m==3(as per Sample Input)
//How can I do that in java
}
System.out.println();
}
Try this
static void swap(String[][] array, int r1, int c1, int r2, int c2) {
String temp = array[r1][c1];
array[r1][c1] = array[r2][c2];
array[r2][c2] = temp;
}
static void vertical(String[][] array) {
int rows = array.length;
int cols = array[0].length;
for (int r = 0; r < rows; ++r)
for (int c = 0; c < cols / 2; ++c)
swap(array, r, c, r, cols - c - 1);
}
static void horizontal(String[][] array) {
int rows = array.length;
int cols = array[0].length;
for (int c = 0; c < cols; ++c)
for (int r = 0; r < rows / 2; ++r)
swap(array, r, c, rows - r - 1, c);
}
public static void main(String[] args) {
String s = ""
+ "2\n"
+ "3 3\n"
+ "abc\n"
+ "def\n"
+ "ghi\n"
+ "V\n"
+ "3 4\n"
+ "1234\n"
+ "5678\n"
+ "9876\n"
+ "H\n";
try (Scanner scanner = new Scanner(s)) {
int cases = scanner.nextInt();
for (int i = 0; i < cases; ++i) {
int rows = scanner.nextInt();
int cols = scanner.nextInt();
scanner.nextLine();
String[][] array = new String[rows][cols];
for (int r = 0; r < rows; ++r)
array[r] = scanner.nextLine().split("");
String operation = scanner.nextLine();
if (operation.equals("H"))
horizontal(array);
else
vertical(array);
for (int r = 0; r < rows; ++r) {
for (int c = 0; c < cols; ++c)
System.out.print(array[r][c]);
System.out.println();
}
}
}
}

Rotating image 90 degree counter clockwise in Java

public static int[][] rotate(int[][] array){
int height = array.length;
int width = array[0].length;
int[][] rotatedArray = array;
for(int col = 0; col < width; col++){
for(int row = 0; row < height; row++){
rotatedArray[row][col] = array[col][row];
}
}
return rotatedArray;
}
This is my code as method to rotate image 90 degree counter-wise, but it doesn't work. I have no idea how to arrange new rows and columns and rotate it properly, how can I fix it? Thanks!
Try rotatedArray[row][col] = array[col][height - row - 1];.
Also, you need to define rotatedarray as a new array. Right now, you're assigning it array, which means they are both referencing the same data.
Here's how you can do it:
public static int[][] rotate(int[][] array) {
int height = array[0].length;
int width = array.length;
int[][] rotatedArray = new int[height][];
for(int row = 0; row < height; row++) {
rotatedArray[row] = new int[width];
for(int col = 0; col < width; col++) {
rotatedArray[row][col] = array[col][height - row - 1];
}
}
return rotatedArray;
}
Note that the height of the original array becomes the width of the new array and vice versa.
By transposing the row & column indices with rotatedArray[row][col] = array[col][row], you are mirroring the image along the diagonal, instead of rotating it. Think about it - any entry where both indices are matching such as array[0][0] or array[1][1] is unchanged. That's not what you want!
I would recommend drawing a picture to see what pattern you see. You can start with very small examples, 2-by-2 or 3-by-3.

Java: array index out of bounds. Looping problems

I'm fairly new to java but, I'm making an encryption program that places each character in a grid. In this case I'll just be using "abcde" as my string. When put through the program, it's supposed to place each character in a 3x2 (height x width) grid. The program reads the grid from top to bottom then moving on to the next row and it'll be read as, "acebd." This part of the program is loading each character into char [height][width].
line length: 5, height: 3, width: 2, longColumn: 1
//longColumn -- the number of valid columns in the last row
static char[][] loadGrid(String line, int width, int height, int longColumn) {
char grid[][] = new char[height][width];
int charCount = 0;
for (int i = 0; i <= line.length()-1; i++){
if (i < line.length()-1) {
for (int c = 0; c < width; c++) {
for (int r = 0; r < height; r++) {
if (r < height - 1 || c < longColumn) {
grid[r][c] = line.charAt(charCount);
charCount += 1;
}
}
}
}
}
return grid;
}
When I run it I get this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at GridEncrypt.loadGrid(GridEncrypt.java:93)
at GridEncrypt.processInput(GridEncrypt.java:65)
at GridEncrypt.main(GridEncrypt.java:19)
To my understanding the charCount isn't going to 4, just staying at 3. I've tired messing around with it but it either just stays at 3 or goes to 5. Also, I'm thinking that it goes through the first two for loops once and then just doesn't go back to it after it runs through the 3rd loop. Which then the 3rd loop is the only one that's being looped properly. Any help is appreciated. Thanks.
I don't see the point of longColumn, and I think you wanted something like
static char[][] loadGrid(String line, int width, int height) {
char grid[][] = new char[height][width];
int charCount = 0;
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c++) {
if (charCount < line.length()) {
grid[r][c] = line.charAt(charCount);
charCount++;
}
}
}
return grid;
}
I would recommend using the debugger, and stepping through the program. Make sure to keep track of array sizes and variables (especially r and c). The error is being caused by (r,c) being outside the array. Also, a few other things.
1.charcount += 1; can be replaced with charcount++;
2. Remember that when dealing with integers, if (r < height - 1) is essentially the same as if(r <= height - 2)
3. The variables i and charcount are saying the same thing anyways, so you can combine those variables.

Printing chars from 2d array java

How do you print chars from a 2D array, column by column instead of row by row? Also how do you get the chars to populate the array? I know you have to use for loop but I keep getting strings which are read row by row.
String command = args[0];
String Text = args[1]; //leters to be
char letters [] = Text.toCharArray();
int m = Text.length(); //number of letters to be decrypted/encrypted
if (command.equals("-encrypt")) {
if ( m / (int) Math.sqrt(m) == Math.sqrt(m) ) { //if m is a perfect square no. eg.4,9,16
int RootM = (int) Math.sqrt(m); //find depth and width of grid, square therfore depth = width
char [][] box = new char [RootM][RootM]; //define and create grid
for (int i=0; i<RootM; i++) {
for (int j=0; j<RootM; j++) {
box[i] = letters; //change this to read each column
System.out.print(Text); //displays encrypted text
}
}
}
else if ( m / (int) Math.sqrt(m) != Math.sqrt(m) ) { //non perfect square digits
int RootM = (int) Math.pow((Math.sqrt(m))+1,2); //overall size of 2d array (depth*width)
int RootN1 = (int) Math.sqrt(RootM); //length of rows & columns
char [][] box = new char [RootN1][RootN1]; //define dimensions of 2d array
for (int i=0; i<RootN1; i++) {
for (int j=0; j<RootN1; j++) {
box[j] = letters; //change this to read each column
System.out.println(Text); //displays encrypted text
char [][] box = new char [5][3];//5 rows, 3 columns
for(int i =0;i<3; i++){
for (int j = 0; j < 5; j++) {//Iterate rows
System.out.println(box[j][i]);//Print colmns
}
}

Categories

Resources