Java: Print a 2D String array as a right-justified table - java

What is the best way to print the cells of a String[][] array as a right-justified table? For example, the input
{ { "x", "xxx" }, { "yyy", "y" }, { "zz", "zz" } }
should yield the output
x xxx
yyy y
zz zz
This seems like something that one should be able to accomplish using java.util.Formatter, but it doesn't seem to allow non-constant field widths. The best answer will use some standard method for padding the table cells, not the manual insertion of space characters.

Here's an answer, using dynamically-generated format strings for each column:
public static void printTable(String[][] table) {
// Find out what the maximum number of columns is in any row
int maxColumns = 0;
for (int i = 0; i < table.length; i++) {
maxColumns = Math.max(table[i].length, maxColumns);
}
// Find the maximum length of a string in each column
int[] lengths = new int[maxColumns];
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
lengths[j] = Math.max(table[i][j].length(), lengths[j]);
}
}
// Generate a format string for each column
String[] formats = new String[lengths.length];
for (int i = 0; i < lengths.length; i++) {
formats[i] = "%1$" + lengths[i] + "s"
+ (i + 1 == lengths.length ? "\n" : " ");
}
// Print 'em out
for (int i = 0; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.printf(formats[j], table[i][j]);
}
}
}

Indeed, if you specify a width for the fields, it should be right-justified.
If you need to have a dynamic padding, minimal for the longest string, you have to walk the array, getting the maximal width, generate the format string with the width computed from this maxima, and use it for format the output.

find the length of the longest string..
left pad all the strings with spaces until they r that length + 1
System.out.print them using 2 nested for loops

Related

How to print first five elements of an matrix in Java

My goal is to implement the following method in parallel:
public static double[][] parallelAddMatrix(double[][] a, double[][] b), then test my program on randomly generated two lists of size 2000 x 2000. Finally I have to output the first 5 elements of matrix a and matrix b, and also the first five elements of the result matrix, which is what I'm having trouble with.
This is the part of my code where I create the first and second matrix.
public static void main(String[] args) {
int var1, var2;
final int matrices = 2000;
// creates first matrix
double[][] matrixA = new double[matrices][matrices];
for(var1 = 0; var1 < matrixA.length; var1++)
for (var2 = 0; var2 < matrixA[var1].length; var2++)
matrixA[var1][var2] = 1;
// creates second matrix
double[][] matrixB = new double[matrices][matrices];
for (var1 = 0; var1 < matrixB.length; var1++)
for (var2 = 0; var2 < matrixB[var1].length; var2++)
matrixB[var1][var2] = 1;
And then later created a function to create the result matrix...
public static double[][] parallelAddMatrix( double [][] a, double[][] b) {
//creates output matrix
double[][] resultMatrix = new double[a.length][a[0].length];
RecursiveAction task = new multiProcess(a, b, resultMatrix);
ForkJoinPool joinPool = new ForkJoinPool();
joinPool.invoke(task);
return resultMatrix;
}
How can I print out the first five elements for each of the three matrices?
I've tried stuff for the first and second matrix such as initializing var3, then under the "matrixA(orB)[var1][var2] = 1;", I put
for (var3 = 0; var3 < 5; var3++) {
System.out.println(var3);
}
and also tried
for (var3 = 0; var3 < 5; var3++) {
System.out.print(matrixA[var1][var2] + "");
}
System.out.println();
Please help on this, and please tell where it would be placed for each one (I might have trouble with brackets).
You'll need a nested for loop to iterate through the matrix, and a counter to see how many entries you've printed. Let's start with the easiest part: iterating over the matrix. I'll assume that the matrix is simply called matrix.
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
}
}
You probably already figured that out. Now we need a counter to count how many times we've printed out an entry from the matrix.
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.println(matrix[i][j]);
num_printed ++;
}
}
Ok. So now we need to stop once we've reached the end. We can't just use one break statement, because, we have two for loops.
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) { // iterate over the rows
for (int j = 0; j < matrix[i].length; j++) { // iterate over the columns
if (num_printed == 5) { // if we've already printed five items, stop
break;
} else { // otherwise, print the next item
System.out.println(matrix[i][j]);
num_printed ++; // increment the counter
}
}
if (num_printed == 5) { // so that we don't go to the next row
break;
}
}
It's worth noting that you could create your own separate method, and only use a return statement:
public void print_five_elements() {
int num_printed = 0;
for (int i = 0; i < matrix.length; i++) { // iterate over the rows
for (int j = 0; j < matrix[i].length; j++) { // iterate over the columns
if (num_printed == 5) { // if we've already printed five items, stop
return;
} else { // otherwise, print the next item
System.out.println(matrix[i][j]);
num_printed ++; // increment the counter
}
}
}
}
More Specialized Approach
This approach allows you to use matrices that have less than five columns. However, since your matrix is 2000x2000, you could go for a much simpler approach. Use zero as the first index, and then just iterate up to five. Just keep in mind that this won't work if you have less than five columns:
public void print_five_elements_for_wide_matrix() {
for (int i = 0; i < 5; i++) {
System.out.println(matrix[0][i]);
}
}
Since the matrices are of size 2000 x 2000, you do not need nested loops to display first 5 elements from each of them.
int i;
//Display first 5 elements of matrixA
for(i=0; i<5; i++) {
System.out.print(matrixA[0][i] + " ");
}
System.out.println();
//Display first 5 elements of matrixB
for(i=0; i<5; i++) {
System.out.print(matrixB[0][i] + " ");
}
System.out.println();
double[][] result = parallelAddMatrix(matrixA, matrixB);
//Display first 5 elements of result
for(i=0; i<5; i++) {
System.out.print(result[0][i] + " ");
}
System.out.println();
Note that the above loops print the first 5 elements of the first row (i.e. row at index, 0) of each matrix. However, if you want to print the first element of the first 5 rows, just swap the indices e.g.
System.out.println(matrixA[i][0] + " ");
Try this:
Think of the first set of brackets as the row and the second set as the column.
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
System.out.print(matrixA[row][col] + " ");
}
System.out.println();
}
Since "multi-dimensional" arrays are really arrays of arrays you can do it like this if you wanted to print out the whole matrix
for (double[] row : matrixA) {
System.out.println(Arrays.toString(row));
}
Because of this, each row can be a different length. So you may have to get the length to print them out like you first wanted to.
for (int row = 0; row < matrixA.length; row++) {
for (int col = 0; col < matrixA[row].length; col++) {
System.out.print(matrixA[row][col] + " " );
}
}
Rows of different length of a "2D" array are known as ragged-arrays.

How to count the numbers of letters for each column in a String [][]?

I want to count the number of letters in a String [][] by column , so far my code is this :
for(int j = 0 ; j<matrix[0].length ;j++){
for(int i = 0 ; i< matrix.length ;i++ )
if (Character.isLetter(matrix[j][i].charAt(j)))
countChar++;
}
System.out.println(countChar + "letters");
return countChar;
but the output of the program counts how many elements the string has
for example if the String is :
String [][] C = {
{"abc", "abcd" , "abcd"},
{"oroeo", "kakakak" , "alsksjk"},
{"abcdef", "asdasdasdasd", "asdasdasdasd"},
};
the result is 9 , but should be 14 (number of letters by column )
Any help is greatly apreciated thank you !
You can define a 2D matrix as an array of rows or an array of columns. I'm assuming you have defined it as an array of rows and now want to get the values in a certain column.
So your data looks like this:
abc abcd abcd
oroeo kakakak alsksjk
abcdef asdasdasdasd asdasdasdasd
three rows and three columns.
to get for example the values in the middle column (with index 1) you would need to get the array elements:
matrix[0][1]
matrix[1][1]
matrix[2][1]
I think you are trying to count the total of the lengths of all values in each column. That would go like this:
// assume that the matrix has at least one row and thas the same number of columns in each row
// take the number of columns in the first row for reference
int numberOfColumns = matrix[0].length;
for(int col = 0; col < numberOfColumns; col++) {
int count = 0;
// iterate over all the rows
for(String[] row : matrix) {
// count the length of the element in position col of this row
count += row[col].length();
}
System.out.printf("%s characters in column %s", count, col);
}
int n = 0;
// iterate row by row
for (int i = 0; i < C.length; i++) {
n += C[i][0].length();
// get the string at index 0 (or 1 or 2.. whichever you want) of the array and append its length
// if you expect the string to contain numbers, then
// run a for-loop on the string and check if its a letter
}
System.out.println(n);
Try below the problem is with your for loop for which the no. of iterations are limited to the size of your matrix:
for(int i = 0 ; i<C[0].length ;i++) {
String matrixElement = C[i][0];
System.out.println(matrixElement);
for(int k =0 ;k < matrixElement.length();k++)
if (Character.isLetter(matrixElement.charAt(k)))
countChar++;
}
Please, format out your code and brush up the loop:
private static int countByColumn(String[][] matrix, int column) {
if (column < 0)
return 0; // Or throw exception
int countChar = 0;
for (String[] line : matrix) {
//DONE: jagged array: it may appear that the line is too short
if (line.length <= column)
continue;
String item = line[column];
for (int i = 0; i < item.length; ++i)
if (Character.isLetter(item.charAt(i)))
countChar += 1;
}
return countChar;
}
Test:
// 14
int test = countByColumn(C, 0);

Select element j in each column of an array in JAVA

I have the array
String[] test_=new String[] {"a b c d", "f g h i","j k l s gf"};
Now i want to create another array that has the elements
{"b d", "g i","k s"}
how can I do this?
I've managed to separate the array into rows using
String split_test[] = null;
for (int j = 0 ; j <= 2 ; j++) {
split_test=test_[j].split("\\s+");
System.out.println(Arrays.toString(split_test));
}
But now I want to separate each of those rows, I tried the solution of
How to Fill a 2d array with a 1d array? Combined with something like this split_test=test_[j].split("\s+"), but I haven't been able to solve it.
Also If I do what they say I have to make the array split_test have a number of specific columns, but what I want is the size of the columns of split_test depend of the array test_. For example in case I want to have an array with the elements {"b d", "g i", "k s gf"}
String[][] split_test = new String[3][2];
for(int row = 0; row < split_test.length; row++) {
for(int col = 0; col < split_test[row].length; col++) {
split_test[row][col] = test_[row];/*I still don't understand how to use the split within the for*/
System.out.println(split_test[row][col]);
}
}
Is there a simpler and more efficient way of doing this?
Thanks
Here is another one.
You can use the substring method of String class.
Or use indexes of the array returned by the split method.
String output[] = new String[test_.length];
String split_test[] = null;
for (int j = 0; j < test_.length(); j++) {
split_test = test_[j].split("\\s+");
// use direct index
// output2[j] = split_test[1] + " " + split_test[3];
// or based on length
output[j] = split_test[1] + " " + split_test[split_test.length - 2];
}
System.out.println(Arrays.toString(output));
Output:
b d
g i
k s
I have used a different approach that works as well. I noticed you only take the uneven indexes, hence my modulo approach:
String[] array = new String[] {"a b c d", "f g h i","j k l s gf"};
String[] result = new String[array.length];
for(int i = 0; i < array.length; i++) {
String subresult = "";
String[] array2 = array[i].split(" ");
for(int j = 0; j < array2.length; j++) {
if(j % 2 == 1)
subresult += array2[j] +" ";
}
result[i] = subresult.trim();
}
You should use a 2 dimentional array, you can create one by doing:
String[][] input=new String[][] {{"a","b","c","d"}, {"f","g","h","i"},{"j","k","l","s"}};
You can then do something like this to retrieve {{"b","d"}, {"g","i"},{"k","s"}}:
String[][] output = new String[input.length][2];
for(int i = 0; i<input.length; i++)
{
output[i] = new String[]{input[i][1],input[i][3]};
}
System.out.println(Arrays.deepToString(output));

Math and Arrays

I'm new to java and still learning. I am having one heck of a time trying to figure out how to create this program. I have tried multiple ways and spent about 4 hours now trying to get this to work and it still wont outprint what I need it to. I need a 10x5 array with the first 25 digits being the index variable squared and the last 25 digits being the index times 3. What it is outprinting is 5 numbers over and over 10 times. But it's like it is not reading the "next index variable". I get: 0.0, 1.0, 4.0, 9.0, 16.0, 0.0, 1.0, 2.0, 4.0, etc.. Here is what I have so far(please don't rate down, I'm trying hard to learn this!):
public class snhu4 {
public static void main(String args[]) {
double alpha[][] = new double [10][5];
for (int col=0; col<=9;col++) {
for (int row=0; row<=4;row++) {
alpha[col][row]= Math.pow(row,2);
System.out.println(alpha[col][row]);
}
}
}
}
I believe you're looking for something like this:
public static void main (String[] args) {
double[][] alpha = new double[10][5];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 5; j++) {
int index = (5 * i + j);
if (index < 25) {
alpha[i][j] = (index * index);
System.out.println("index(" + index + ")^2 =" + alpha[i][j]);
} else {
alpha[i][j] = (3 * index);
System.out.println("3*index(" + index + ") = " + alpha[i][j]);
}
}
}
}
You need an index variable initialized to zero outside of the loops and incremented (index++) inside the inner loop. Then you can perform the calculations on the index (0-49) rather than the row variable, which keeps looping 0-4. You'll also need a conditional (if statement) that performs one calculation if index is < 25 and a different calculation if index >= 25.
This is just a generalised version, compared to the accepted answer. It will give the same output, though.
public static void main(String args[]) {
double alpha[][] = new double [10][5];
int index = 0;
for (int row = 0; row < alpha.length; row++)
{
for (int col = 0; col < alpha[row].length; col++)
{
if (index < 25)
alpha[row][col] = Math.pow(index, 2);
else
alpha[row][col] = index * 3;
index++;
System.out.println(alpha[row][col]);
}
System.out.println("" + '\n');
}
}
You're always using the row variable to calculate the assignment value, I think you should combine the values of row and col (or maybe use an index as aetheria says), something like this:
double alpha[][] = new double[10][5];
for (int col = 0; col <= 9; col++) {
for (int row = 0; row <= 4; row++) {
if (col < 5) //if column >= 5 that means that you just passed the 25 index
alpha[col][row] = Math.pow(row + (col*row), 2);
else {
alpha[col][row] = Math.pow(row + (col*row), 3);
}
}
}
I couldn't test it (my eclipse is totally crushed) but I think that will give you the idea (probably you will need to play with the "row + (col*row)" part, when one of the variables is 0 it will not fit your needs). Hope this helps, regards.

Put two arrays to Jtable rows

I have two arrays, which is equal in terms of number of elements. I want to put it in a JTable rows (like in the ascii table example from bellow). I'm using table model and a loop for both arrays, but I archive something else (see print screen).
Note: I want to maintain the correspondence between elements of both arrays, like in the ascii table example.
Integer[] intArray = new Integer[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
intArray[i] = Integer.parseInt(stringArray[i]);
}
System.out.println(Arrays.toString(intArray)); //output [285, 715, 1437, 1749]
Integer[] intArray1 = new Integer[stringArray1.length];
for (int i = 0; i < stringArray1.length; i++) {
intArray1[i] = Integer.parseInt(stringArray1[i]);
}
System.out.println(Arrays.toString(intArray1)); //output [0, 0, 1087, 0]
DefaultTableModel modelPeaks = new DefaultTableModel();
JTable table = new JTable(modelPeaks);
modelPeaks.addColumn("1st Column");
modelPeaks.addColumn("2nd Column");
for (int i = 0; i < intArray.length; i++) {
for (int j = 0; j < intArray1.length; j++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[j]});
}
}
The output is:
But I want to archive this:
+--------------------+--------------------+
+ 1st Column + 2nd Column +
+--------------------+--------------------+
+ 285 + 0 +
+ 715 + 0 +
+ 1437 + 1087 +
+ 1749 + 0 +
+--------------------+--------------------+
I think that is from the loop, but I can't figure out how to fix it. Someone can help me? And thanks in advance for your time.
The last loop should read
for (int i = 0; i < intArray.length; i++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[i]});
}
Always make sure that both array have the same length.
If the arrays are both the same length you can use the same iterator for both:
for (int i = 0; i < intArray.length; i++) {
modelPeaks.addRow(new Object[]{intArray[i], intArray1[i]});
}

Categories