Convert Java 1D array into 2D array - java

No matter what code snippet that I try, of which I find on the Internet (mostly from Stack Exchange/Overflow), I can't figure out how to convert (or "assign") elements of a one-dimensional array into a two-dimensional array.
String str = in.next(); // Read the incoming text file and store it as a string
char[] oneDcharArray = str.toCharArray(); // Convert the string into a 1D array
maze = new char[numberOfRows][numberOfColumns]; // Assign row/column size to 2D array
int count = 0;
for (row = 0; row < numberOfRows; row++)
{
for (column = 0; column < numberOfColumns; column++)
{
// Convert 1D array into 2D array
maze[row][column] = oneDcharArray[count]; // Error: ArrayIndexOutOfBoundsException
count++;
}
}
The answer by Jags below works well, but it's not perfect. It prints:
Row 0: ++++++++++
Row 1: S+++++++++
Row 2: ++++++++++
Row 3: +++++ 0000 0000 0000 0000 0000
Row 0: ++++++++++
Row 1: OOOOOOOOOO
......

//rows*col must equal to single d array
public static char[][] conversion( char[] array, int rows, int cols )
{
if (array.length != (rows*cols))
throw new IllegalArgumentException("Invalid array length");
char[][] array2d = new char[rows][cols];
for ( int i = 0; i < rows; i++ )
System.arraycopy(array, (i*cols), array2d[i], 0, cols);
return array2d;
}

Below sample code should work. You need to loop through oneDcharArray rather then rows/columns. But note that, it all depends on what is your requirement to create maze. i.e how exactly you want to devide available chars into N x M array.
public class OneToTwo {
public static void main(String[] args) {
String str = "This is my test string with some words in it.";
char[] oneDcharArray = str.toCharArray(); // Convert the string into a 1D array
int numberOfColumns = 10;
int numberOfRows = (int)Math.ceil(oneDcharArray.length/numberOfColumns) + 1; // its not modulo
char[][] maze = new char[numberOfRows][numberOfColumns]; // Assign row/column size to 2D array
int count = 0;
int row =0 ,column = 0;
for (char c:oneDcharArray) {
if(column >= numberOfColumns) {
row++;
column = 0;
}
maze[row][column] = c;
column++;
}
//Test it
for (row = 0; row < numberOfRows; row++) {
System.out.print("Row "+row+": ");
for (column = 0; column < numberOfColumns; column++) {
// Convert 1D array into 2D array
System.out.print(maze[row][column]);
count++;
}
System.out.println();
}
}
}
output
Row 0: This is my
Row 1: test stri
Row 2: ng with so
Row 3: me words i
Row 4: n it.

Related

How to remove the empty element in multi dimentional string array?

String[][] array = {{"abcd",""},{"asdf",""},{"",""},{"",""},{"",""},{"",""}};
I want to remove the {"",""} elements from the array.
How can I do it in Java?
Remove?
You cannot change the size of an existing array.
If you want to create a new array with only these elements, count the length of each array, create a new array based on those lengths, add elements to the new array.
String[][] array= {{"abcd",""},{"asdf",""},{"",""},{"",""},{"",""},{"",""}};
//Assuming you want a 1-D array
int valuesPresent = 0;
for (int i = 0; i < arrray.length; i++) {
for (int j = 0; i < arrray[i].length; i++) {
if (array[i][j] != "") {
valuesPresent++;
}
}
}
//Now you know how many values are there, so initialize a new array of that size
String[] answer = new String[valuesPresent];
//Now add all the values to it
int index = 0;
for (int i = 0; i < arrray.length; i++) {
for (int j = 0; i < arrray[i].length; i++) {
if (array[i][j] != "") {
answer[index] = array[i][j];
index++;
}
}
}
To get a 2-d array, easy to understand:
//Just reordered input so we can understand better
String[][] array= {{"abcd","zxcs"}, //Row 0, col 0 = abcd and col 1 = zxcs
{"asdf",""}, //Row 1, col 0 = asdf and col 1 = ""
{"",""}}; //Row 2, col 0 = "" and col 2 = ""
//Counts how many columns have values(are not equal to "") in each row
int rowsWithValues = 0; //Counts how many rows have at least 1 value. Here, 2
for (int row = 0; row < arrray.length; row++) {
for (int col = 0; col < arrray[row].length; col++) {
if (array[row][col] != "") {
rowsWithValues++; //Since there's a col with value for this row
break; //If any one value has been found, no need to check other cols
}
}
}
//Now we know how many rows we need in the result array: 2 (row 2 has no values)
String[][] result = new String[2][];
//We need to add the 2 rows with values now
int arrayIndex = 0; //Points to next empty index in result[][]
for (int row = 0; row < arrray.length; row++) {
int colsWithValues = 0; //Cols with values for each row
for (int col = 0; col < arrray[i].length; col++) {
if (array[row][col] != "") {
colsWithValues ++; //Col with value found for this row
}
}
//Eg. For row 0, colsWithValues will be 2, since 2 cols have values(abcd, zxcs)
//We need to add these 2 cols as a single array to result
String[] currentRow = new String[colsWithValues]; //Will be 2 here for row 0
int rowIndex = 0; //Points to next empty column in currentRow[]
for (int col = 0; col < array[row].length; col++) {
if (array[row][col] != "") {
currentRow[rowIndex] = array[row][col];
}
}
//After this, for row 0, currentRow will be {abcd, zxcs}
//Just add it to our result
result[arrayIndex] = currentRol;
//After 1st iteration, result will be {{"abcd", "zxcs"}, {}}
//During 2nd iteration, arrayIndex == 1, currentRow == {"asdf"}
//On adding it to result[1], result will be {{"abcd", "zxcs"}, {"asdf"}}
To start with, don't compare two Strings for equality using == or !=, even for String Arrays:
if (array[i][j] != "") {
In the case above, it should be:
if (!array[i][j].equals("")) {
If you're not quite up to Streams yet then this is one way that might interest you:
public static String[][] removeNullStringRows(String[][] array) {
if (array == null || array.length == 0) {
return null;
}
int validCount = 0; // Row Index Counter for the new 2D Array
/* Find out how may rows within the 2D array are valid
(where the do not consist of Null Strings {"", ""}).
This let's you know how many rows you need to initialize
your new 2D Array to. */
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
if (!array[i][j].equals("")) {
validCount++;
break;
}
}
}
/* Declare and initialize your new 2D Array. This is
assuming the column count is the same in all rows. */
String[][] array2 = new String[validCount][array[0].length];
validCount = 0; // Used as an index increment counter for the new 2D Array
// Iterate through the supplied 2D Array and weed out
// the bad (invalid) rows.
for (int i = 0; i < array.length; i++) { // Iterate Rows...
for (int j = 0; j < array[i].length; j++) { // Iterate Columns
/* Does this row contain anything other than a Null String ("")?
If it does then accept the entire Row into the new 2D Array. */
if (!array[i][j].equals("")) {
// Retrieve all the columns for this row
for (int k = 0; k < array[i].length; k++) {
array2[validCount][k] = array[i][k];
}
// The above small 'for' loop can be replaced with:
// System.arraycopy(array[i], 0, array2[validCount], 0, array[i].length);
validCount++; // Increment our Row Index Counter for the new 2D Array
break; // Get out of this column iterator. We already know it's good.
}
}
}
return array2; // Return the new 2D Array.
}
To use this method you might do it this way:
// Your current 2D Array
String[][] array = {
{"abcd",""}, {"asdf",""}, {"",""},
{"",""}, {"",""}, {"",""}
};
// If the supplied 2D Array is null contains no rows
// then get out of here.
if (array == null || array.length == 0) {
return;
}
// Display the original 2D Array (array) in the Console window
System.out.println("The original 2D Array:");
for (int i = 0; i < array.length;i++) {
System.out.println(Arrays.toString(array[i]));
}
// Remove all rows that contain all Null String Columns.
// Make your Array equal what is returned by our method.
array = removeNullStringRows(array);
// Display the new 2D Array (array) in the Console window.
System.out.println();
System.out.println("The New 2D Array:");
for (int i = 0; i < array.length;i++) {
System.out.println(Arrays.toString(array[i]));
}
And your Console Window output should look like:
The original 2D Array:
[abcd, ]
[asdf, ]
[, ]
[, ]
[, ]
[, ]
The New 2D Array:
[abcd, ]
[asdf, ]
I am assuming here that, the nested array could be of any size not just of 2 elements.
Create a predicate that takes Stream<String> and checks if any element is not null and non-empty.
String[][] array= {{"abcd",""},{"asdf",""},{"",""},{"",""},{"",""},{"",""}};
Predicate<Stream<String>> arrayPredicate = element ->
element.anyMatch(ele ->Objects.nonNull(ele) && !ele.isEmpty());
Now stream over the original array and filter the inner array based on a predicate and collect it in a new array.
String[][] copyArray = Arrays.stream(array)
.filter(arr -> arrayPredicate.test(Arrays.stream(arr)))
.toArray(String[][]::new);
array = copyArray; // reassign to array
You can filter out all null and empty elements from this 2d array as follows:
String[][] array = {{"abcd",""},{"asdf",""},{"",""},{"",""},{"",""},{"",""}};
String[][] nonEmptyArray = Arrays.stream(array)
.map(row -> Arrays.stream(row)
// filter out 'null' elements and empty strings
.filter(e -> e != null && e.length() > 0)
// an array of non-empty strings or an empty
// array if there are no such strings
.toArray(String[]::new))
// filter out empty arrays
.filter(row -> row.length > 0)
// an array of non-empty arrays
.toArray(String[][]::new);
// output
System.out.println(Arrays.deepToString(nonEmptyArray)); // [[abcd], [asdf]]
private String[][] removeFromArray(String[][] source, String[] objToRemove) {
return Arrays.stream(source)
.filter(element -> !Arrays.equals(element , objToRemove))
.toArray(String[][]::new);
}
void example() {
final String[] empty = new String[]{"", ""};
String[][] array = {{"abcd", ""}, {"asdf", ""}, {"", ""}, {"", ""}, {"", ""}, {"", ""}};
array = removeFromArray(array, empty);
}
Something like that should work

1-Dimensional array -> 2D array

So i'm a beginner;
The task is to convert a given string into the array, the string always has the first characcter as the amount of rows and the second character as the amount of columns.
My problem is to solve how to move the rest of the string 's' into the 2D array from the 1D array.
Thanks in advance!
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] s = scanner.nextLine().split(" ");
int arows = Integer.parseInt(s[0]);
int acols = Integer.parseInt(s[1]);
int[][] cells = new int[arows][acols];
for (int col = 0; col < acols; col++){
for (int row = 0; row <= arows;row++){
cells[row][col] = Integer.parseInt(s[2]);
}
}
}
}
You need to implement a counter for your for-loops to iterate through the input string. What you are doing right now is to fill your 2D-Array with the third element of your string.
One solution would be to just declare a variable i = 2, and increment it for each pass of the inner for-loop.
int i = 2
for (int col = 0; col < acols; col++){
for (int row = 0; row < arows;row++){
cells[row][col] = Integer.parseInt(s[i]);
i++;
}
}
Edit: removed <= in row loop, changed the initial value of the index to 2
This is the solution, you have to put another iterator, and initialize it to 2, so to skip the first two elements of s[]
int i = 2;
for (int col = 0; col < acols; col++){
for (int row = 0; row < arows;row++){
cells[row][col] = Integer.parseInt(s[i]);
i++;
}
}

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);

Copy 2D array and increase size to fill new values

I would like to first apologize if my question is worded badly. I have an exam tmmrw and the prof gave a sample final exam for us to practice with. He unfortunately isn't responding with the solutions on the forum so I am trying to provide solutions on there. I seem to be stuck on this question. I have to write a method that accepts and NxM array filled with integer values as a parameter. The method is to return an (N+1)x(M+1) array which contains the contents of the original array in the first N rows and M columns plus a count of items greater than or equal to zero in each row/column at the end of that row/column and put the value -1 in the bottom right corner. for example.
1 -2 0 returns 1 -2 0 2
3 -4 -5 3 -4 -5 1
2 0 1 -1
I seem to be able to copy the array yet I am puzzled as to how I can enter the values in the outer parts of the new array. Here is what I have so far.
public static void main(String[] args) {
int[][] arr = { { 1, -2, 0 }, { 3, -4, -5 } };
int[][] newMatrix = processing2D(arr);
printArray(newMatrix);
}
//Method where I am having problems
public static int[][] processing2D(int[][] arr) {
int[][] matrix = new int[arr.length][arr[0].length];
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
// once I reach the last pos I enter the count
// of numbers greater than or equal to zero in that row/col
matrix[row][col] = arr[row][col];
}
}
// assign the corner -1 here
return matrix;
}
public static void printArray(int[][] list) {
for (int row = 0; row < list.length; row++) {
for (int col = 0; col <= list.length; col++) {
System.out.print(list[row][col] + " ");
}
System.out.println();
}
}
First off you are initializing the new array wrong it should be
int[][] matrix = new int[arr.length+1][arr[0].length+1];
You don't want it to be the same length you want it to be the length +1. Also in your for loops you want to go by the length of arr not matrix since thats what you're taking from. While putting the values into the new N+1xM+1 array, increment the value of the corresponding last element in that row and column by 1 if it is >=0.
for (int row = 0; row < arr.length; row++) {
for (int col = 0; col < arr[0].length; col++) {
// once I reach the last pos I enter the count
// of numbers greater than or equal to zero in that row/col
if(arr[row][col]>=0){
matrix[row][matrix[row].length-1] = matrix[row][matrix[row].length-1] + 1;
matrix[matrix.length-1][col]= matrix[matrix.length-1][col] + 1;
}
matrix[row][col] = arr[row][col];
}
After putting all the values back into the new N+1xM+1 array you should now take the values in the n sized and m sized arrays and put them into the corresponding slot in the N+1xM+1 array. After that just put the -1 in the bottom right slow manually.
matrix[matrix.length-1][matrix[0].length-1]=-1;
In your process2D method start off by creating an array with the correct size which has 1 more row and 1 more column than the original:
int[][] matrix = new int[arr.length+1][arr[0].length+1];
Then to populate the matrix array you do like you were doing before, but you need to take care not to reference an index of the arr array that is out of bounds. Because your matrix index is bigger than arr. If you are populating the new indexes then you can just use random numbers.
if(row < arr.length && col < arr[0].length)
{
matrix[row][col] = arr[row][col];
}
else
{
matrix[row][col] = new Random().nextInt(10);
}
So here is the full method process2D:
public static int[][] processing2D(int[][] arr) {
int[][] matrix = new int[arr.length+1][arr[0].length+1];
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[0].length; col++) {
// once I reach the last pos I enter the count
// of numbers greater than or equal to zero in that row/col
if(row < arr.length && col < arr[0].length)
{
matrix[row][col] = arr[row][col];
}
else
{
matrix[row][col] = new Random().nextInt(10);
}
}
}
// assign the corner -1 here
return matrix;
}

Java Diagonal Matrix

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();
}
}

Categories