Print A 2D Array As A Grid? (Java) - java

I've run into a bit of a conundrum in a personal Java project I've been working on. I want to print a two-dimensional array of Strings in the form of a table. Not the Strings by themselves, but with row and column labels as well (think Microsoft Excel). This is what I envision the finished product to be, with asterisks representing where the Strings should go.
| A | B | C | D | E | F | G |
----+---------+---------+---------+---------+---------+---------+---------+
1 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
2 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
3 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
4 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
5 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
6 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
7 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
8 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
9 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
10 | * | * | * | * | * | * | * |
----+---------+---------+---------+---------+---------+---------+---------+
I know that this will use a nested forward loop, and that the logical process would be to put the String values in the inner loop, like "example[i][j]" type format. I'm just so confused as to how I go about getting the design around the cells in the right format, limiting each String to 10 characters like how Excel limits their cell size when shrunken down. Do I use substring for that? Do I use printf to get the 10th row correctly spaced?
Any pointers are greatly appreciated, I've never been stumped quite like this before.

The first line should be easy enough, assuming you don't exceed 26 columns, i.e. column name is just A to Z.
The even lines are all a lead-in of ----+, followed by columnCount repeats of ---------+.
The odd lines (except first), are a lead-in of 999 |, where 999 is a row number, right-justified, with leading spaces. That can be done with printf() or String.format() with a format string of
"%3d |".
Following the lead-in are columnCount repeats of a string value, trimmed and center-aligned to 9 characters, followed by a |.
To center-align to 9 characters, do the following:
If length > 9, trim to 9 (yes, using substring()).
Otherwise, calculate spaces needed, i.e. spacesTotal = 9 - trimmedLength.
Calculate spaces on left: spaceBefore = spacesTotal / 2.
Calculate spaces on right: spaceAfter = spacesTotal - spaceBefore.
By doing it that way, an odd number of spaces such as 5, becomes 2 before and 3 after.
Now print spaceBefore spaces, the (trimmed) text value, then spaceAfter spaces, and a |.

public static void printStringGrid(String[][] array){
System.out.print(" |");
for (int i = 0; i < array[0].length; i++){
System.out.print(" ");
System.out.print((char)('A' + i));
System.out.print(" |");
}
System.out.println();
for (int i = 0; i < array.length; i++){
System.out.print("----+");
for (int j = 0; j < array[0].length; j++){
System.out.print("---------+");
}
System.out.println();
System.out.print(" " + (i + 1) + " |");
for (int j = 0; j < array[0].length; j++){
if (array[i][j].length() < 10){
int spaces = (9 - array[i][j].length()) / 2;
for (int k = 0; k < spaces; k++){
System.out.print(" ");
}
System.out.print(array[i][j]);
for (int k = 0; k < (9 - array[i][j].length()) - spaces; k++){
System.out.print(" ");
}
}
else{
System.out.print(array[i][j].substring(0, 9));
}
System.out.print("|");
}
System.out.println();
}
}

Related

While loop gets terminated before condition is met when backtracking

I'm trying to write an iterative program that will help me palce 4 queens on a 4x4 board without them hitting each other. The problem is after looping through each position and backtracking a couple of times my main while loop that keeps looping until a solution is found gets terminated and the program ends even though the condition is not yet met.
I tried the following code:
static int[] solve(char[][] board){
int[] position = new int[4];
int row = 0;
int column = 0;
while(row < 4){
for(boolean check; column < board.length; column++){
System.out.println("["+row+","+column+"]");
check = true;
for(int queen= 0; queen < row; queen++){
if (position[queen] == column || queen- position[queen] == row - column || queen + position[queen] == row + column) {
check = false;
break;
}
}
if(check){
position[row] = column;
column = 0;
row++;
}
if(column > 2){
column = position[--row];
}
}
}
return position;
}
I'm currently getting the following output:
| Q | X | X | X |
| X | X | X | Q |
| X | Q | X | X |
| Q | X | X | X |
To check when exactly the while loop is getting terminated I printed the location (row and column)
System.out.println("["+row+","+column+"]"); and got the following:
[0,0][1,0][1,1][1,2][2,0][2,1][2,2][2,3][1,3][2,0][2,1][3,0][3,1][3,2][3,3][2,2][2,3]
After backtracking to [2,3] the while loop ends even though my row count is still less than 4.
I was expecting the following output:
| X | Q | X | X |
| X | X | X | Q |
| Q | X | X | X |
| X | X | Q | X |
I tried the code in a different compiler and still got the same wrong output. Is there a logical mistake that I missed out?
I'm new to programming so I'm still trying to get the hang of the fundamentals.

populating and printing a 2D array given text file containing characters

im trying to print out a text file into a grid-like format after pulling them from a text file. Similar to this method, creating a 2 level for looping going through each row and column. However im not sure the process how it differs when dealing with characters rather than numbers.
example of text file im trying to replicate, excluding the first numbers
8 10
+-+-+-+-+-+-+-+-+-+
| |
+ +-+-+-+ +-+-+-+ +
| | | |
+ + +-+-+-+-+-+ + +
| | | | | |
+ + + +-+-+-+ + + +-+
| | | | | | | S|
+ + + + +-+ + + + +-+
| | | |E| | | |
+ + + +-+ +-+ + + +
| | | | | |
+ + +-+-+-+-+-+ + +
| | | |
+ +-+-+-+-+-+-+-+ +
| |
+-+-+-+-+-+-+-+-+-+
static void readMazeFile(String mazefile) throws FileNotFoundException {
Scanner mazeIn = new Scanner (new File (mazefile));
int height = mazeIn.nextInt();
int width = mazeIn.nextInt();
System.out.print(width);
System.out.print(height);
// get array height & width
int arrayHeight = (height*2)+1;
int arrayWidth = (width*2)+1;
System.out.print(arrayHeight);
System.out.print(arrayWidth);
// create new array set variables
char mazeAsArray[][] = new char[arrayHeight][arrayWidth];
int charCount = 0;
//populate and print array
System.out.print("-------------\n");
for (int r = 0; r < 9; r++){
for (int c = 0; c < 9; c++){
System.out.print(mazeAsArray[r][c]);
}
}
}
thank you
How do i get characters in a file into a 2D array in Java?
Most of the problems are answered in that link. First of all you are not assigning anything into the array. I'll copy my answer from that link here.
for (int row = 0; row < arrayheight; row++)
{
if(!mazein.hasNextLine())
break; // if there is no more lines to read, break the loop
String line = mazein.nextLine();
Char[] chars = line.toCharArray();
for (int col = 0, i = 0; (col < arraywidth && i < chars.length); col++,i++)
{
mazeAsArray[row][col] = chars[i];
System.out.print(mazeAsArray[row][col]);
}
}
Update:
I see your file don't have a regular number of characters in each line. You'll have to count the number of lines for the height and the number of characters in the longest line for the width or you could just input them yourself.

Complexity in tilde notation of nested for loops

How do I find the complexity in tilde notation of the following algorithm:
for (int j = 0; j < N; j++) {
for (int k = j + 1; k < N; k++) {
array[k] = array[j];
}
array[j] = k
}
I've made a table with how many times the inner for-loop loops if N = 9:
| j | # of loops |
|:-----------|------------:|
| 0 | 8 |
| 1 | 7 |
| 2 | 6 |
| 3 | 5 |
| 4 | 4 |
| 5 | 3 |
| 6 | 2 |
| 7 | 1 |
| 8 | 0 |
As you evaluate, the number of inner iterations decreases linearly from 8 down to 0, i.e. it is 4 on average, for a total of 4.9=36.
More generally, the average is (N-1)/2 and the total N.(N-1)/2.
Consequently, I(N) ~ N²/2, in terms of the iteration count.
In terms of memory accesses (R+W), it's the double: A(N) ~ N². (The extra access in the outer loop adds a negligible N contribution.)

how to print this horizontally?

Hey guys if you run this code with the given input you will get a vertical ruler
i'm trying to get a horizontal ruler using the given recursive functions any idea how to get there or hints ???
public class Ruler {
// draw a tick with no label
public static void drawOneTick(int tickLength) {
drawOneTick(tickLength, -1);
}
// draw one tick
public static void drawOneTick(int tickLength, int tickLabel) {
for (int i = 0; i < tickLength; i++)
System.out.print("-");
if (tickLabel >= 0)
System.out.print(" " + tickLabel);
System.out.print("\n");
}
public static void drawTicks(int tickLength) {
if (tickLength > 0) {
drawTicks(tickLength-1);
drawOneTick(tickLength);
drawTicks(tickLength-1);
}
}
public static void drawRuler(int nInches, int majorLength) {
drawOneTick(majorLength, 0);
for (int i = 1; i <= nInches; i++) {
drawTicks(majorLength-1);
drawOneTick(majorLength, i);
}
}
public static void main(String[] args) {
drawRuler(3,4);
}
}
Assuming u want to do Ruler like this:
0 1 2 3 4 5
| | | | | |
| | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It will be hard to it via recursive methods, because you've limited with print/println(), and because text is 1D ^^
So you wont be able to draw whole "tickline" in 1 method, no, tickline with height N will take N+1 printlines.
But, as you see, i've achieved this ruler, only with loops:
SPOLER!
package com.company;
public class Main {
private static String drawLabels(int count, int offset) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= count; i++) {
sb.append(i);
for (int spaces = 0; spaces < offset; ++spaces) {
sb.append(' ');
}
}
return sb.toString();
}
private static String drawTicks(int count, int offset) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= count; i++) {
sb.append('|');
for (int spaces = 0; spaces < offset; ++spaces) {
sb.append(' ');
}
}
return sb.toString();
}
public static void drawRuler(int nInches, int majorLength) {
// labels part
int offset = (int) Math.pow(2, majorLength - 1) - 1;
System.out.println(drawLabels(nInches, offset));
// rest
for (int line = majorLength; line > 0; --line) {
int ticksOffset = (int) Math.pow(2, line - 1) - 1;
int ticksNumber = nInches * (int) Math.pow(2, majorLength - line);
System.out.println(drawTicks(ticksNumber, ticksOffset));
}
}
public static void main(String[] args) {
drawRuler(5,5);
}
}
Here is a solution more inline with your example. You can still do it with recursion without having to use the power function to calculate the position of the tick.
I suggest to start with a smaller problem: How to draw the minor ticks between the major ticks. We can use the recursion for this one. We also have to realize that we can not anymore print the entire tick at once (as Fen1kz correctly mentioned) because it spans across multiple lines. We will have to loop over the number of lines and in the tick function either draw a tick or an empty space based on which line we are drawing. Once we have this we can easily draw one set of minor ticks. After that it is not too hard to add the rest of the code to repeat the previous and add the major ticks.
For completeness here is the whole code:
public class Ruler {
private static void drawMinorTicks(int line, int ticks) {
if (ticks > 1) {
drawMinorTicks(line, ticks - 1);
}
if (line <= ticks) {
System.out.print('|');
} else {
System.out.print(' ');
}
if (ticks > 1) {
drawMinorTicks(line, ticks - 1);
}
}
private static void drawSingleMajorTick(int line, int ticks, int label) {
if (line <= ticks) {
System.out.print('|');
} else {
System.out.print(label);
}
}
private static void drawMajorTicks(int inches, int line, int ticks) {
drawSingleMajorTick(line, ticks, 0);
for (int i = 1; i <= inches; i++) {
drawMinorTicks(line, ticks - 1);
drawSingleMajorTick(line, ticks, i);
}
}
private static void drawRuler(int inches, int ticks) {
for (int i = 1; i <= ticks + 1; ++i) {
drawMajorTicks(inches, i, ticks);
System.out.println();
}
}
public static void main(String[] args) {
drawRuler(5, 5);
}
}
And the output is:
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | | | | | | | | | | | |
| | | | | | | | | | |
| | | | | |
0 1 2 3 4 5

For loop output when scaling figure in java

I have been unable to get my for loop to run right number of times with my "figure" when scaling.
The LINES constant here is the scaling "number".
The problem i am facing lies here i think:
for(int k = 0; k < LINES; k++){
System.out.print("*******");
}
It is supposed to make a line of * at the bottom.
This is my whole code which produces a stairs figure of some kind
public class PP5 {
public static int j;
public static final int LINES = 5;
public static void main(String[] args) {
for(j = 0 ; j < LINES; j++){
fSpaces();
System.out.print(" o *******");
bSpaces();
System.out.println("*");
fSpaces();
System.out.print(" /|\\ *");
bbSpaces();
System.out.println("*");
fSpaces();
System.out.print(" / \\ *");
bbSpaces();
System.out.println("*");
}
for(int k = 0; k < LINES; k++){
System.out.print("*******");
}
}
public static void fSpaces(){
for(int i = (LINES-1); i > j; i--){
System.out.print(" ");
}
}
public static void bSpaces(){
for(int i = 0; i < j; i++){
System.out.print(" ");
}
}
public static void bbSpaces(){
for(int i = 0; i < j+1; i++){
System.out.print(" ");
}
}
}
Any optimizations is highly appreciated.
Thanks
you require 38 stars and you are printing 35
38=(6(Every increment) * 6 (No of times) )+2 (first increment is of 8[6+2])
No of times =6 Because indexing starts from 0 (0,1,2,3,4,5) so in actual counting is 6
so use
for(int k = 0; k <(LINES+1)*6; k++){
System.out.print("*");
}
System.out.print("**");// last star
Output:
o ********
/|\ * *
/ \ * *
o ******* *
/|\ * *
/ \ * *
o ******* *
/|\ * *
/ \ * *
o ******* *
/|\ * *
/ \ * *
o ******* *
/|\ * *
/ \ * *
**************************************
To get effect similar to this
o ********
/|\ * |*
/ \ * |*
o ******* |*
/|\ * | |*
/ \ * | |*
o ******* | |*
/|\ * | | |*
/ \ * | | |*
o ******* | | |*
/|\ * | | | |*
/ \ * | | | |*
o ******* | | | |*
/|\ * | | | | |*
/ \ * | | | | |*
**************************************
|_____|_____|_____|_____|_____|_____|_
you need to notice that each of this part |_____
has six characters so you will need to use six * and print them LINES + 1 times since there are LINES + 1 |_____ parts.
This will generate
************************************|_
from
|_____|_____|_____|_____|_____|_____|_
so you will need to add last two * manually so change your last loop to
for (int k = 0; k <= LINES; k++) {
System.out.print("******");//reduce star numbers by one
}
System.out.print("**");//and add this line
In your implementation just replace
for(int k = 0; k < LINES; k++){
System.out.print("*******");
}
with
for(int k = 0; k < STEPS+1; k++){
System.out.print("******");
}
System.out.print("**");
The motivation is that each step you add 7 * with one overlapping. This means that you need to add 6 * not 7. You add 1 time more to match the top part (but 2 * are missing: 1 because the top line is made of 7* and one for the column).

Categories

Resources