Convert string into two dimensional string array in Java - java

I like to convert string for example :
String data = "1|apple,2|ball,3|cat";
into a two dimensional array like this
{{1,apple},{2,ball},{3,cat}}
I have tried using the split("") method but still no solution :(
Thanks..
Kai

String data = "1|apple,2|ball,3|cat";
String[] rows = data.split(",");
String[][] matrix = new String[rows.length][];
int r = 0;
for (String row : rows) {
matrix[r++] = row.split("\\|");
}
System.out.println(matrix[1][1]);
// prints "ball"
System.out.println(Arrays.deepToString(matrix));
// prints "[[1, apple], [2, ball], [3, cat]]"
Pretty straightforward except that String.split takes regex, so metacharacter | needs escaping.
See also
Regular expressions and escaping special characters
Java Arrays.equals() returns false for two dimensional arrays.
Use Arrays.deepToString and Arrays.deepEquals for multidimensional arrays
Alternative
If you know how many rows and columns there will be, you can pre-allocate a String[][] and use a Scanner as follows:
Scanner sc = new Scanner(data).useDelimiter("[,|]");
final int M = 3;
final int N = 2;
String[][] matrix = new String[M][N];
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
matrix[r][c] = sc.next();
}
}
System.out.println(Arrays.deepToString(matrix));
// prints "[[1, apple], [2, ball], [3, cat]]"

Related

Create a matrix from a string

Suppose a string s = "1 2\n3 4"; the goal is to create a matrix
$ \begin{bmatrix}
1 & 2 \\
3 & 4
\end{bmatrix} $
I have the following code :
public static String[] buildFrom(String s) {
String lines[] = s.split("\\r?\\n");
String newlines[] = new String[lines.length];
int i;
for (i = 0; i < lines.length; i++)
newlines[i] = Arrays.toString(lines[i].split("\\s+"));
return newlines;
The output is [[1, 2], [3, 4]]
It seems to be a String[], However I need a String[][]. The issue seems to be the usage of Arrays.toString but I don't know what else I could use.
Any help would be welcome.
This will return you a String[][] as you seem to want:
public static String[][] buildFrom(String s) {
String[] lines = s.split("\\R");
String[][] matrix = new String[lines.length][];
for (int i = 0; i < lines.length; i++) {
matrix[i] = lines[i].split("\\s+");
}
return matrix;
}
You may want to do additional checks to ensure your matrix is valid such as all rows having the same number of elements.
Your main issue is that you were declaring your output variable to be a String[] rather than a String[][] like you really wanted and thus you could only set its indices (the rows in this case) to be a String rather than a String[]. So it seems you used Arrays.toString(String[]) to convert the String[] you wanted for the row into a String to get around that compile error.

Java parsing command line arguments ( args[]) into an int[][] Type

Can somebody please tell me how to parse the following into an int[][] Type. This is the structure of numbers which are typed into the java args "1,2;0,3 3,4;3,4 " (the first 4 numbers should represent a matrix as well as the last 4 numbers; so i need both parsed as a int[][] ) but how can i take this and parse it into an int[][] type ?
First thing would be this i guess :
String[] firstmatrix = args[0].split(";");
String[] rowNumbers = new String[firstmatrix.length];
for(int i=0; i< firstmatrix.length; i++) {
rowNumbers = firstmatrix[i].split(",");
}
but i cant get it to work out -.-
Edit : At first thank you for all your help. But i should have mentioned that exception handling is not necesarry. Also, i am only allowed to use java.lang and java.io
edit 2.0: Thank you all for your help!
public static void main(String[] args) throws IOException {
List<Integer[][]> arrays = new ArrayList<Integer[][]>();
//Considering the k=0 is the show, sum or divide argument
for(int k=1; k< args.length; k++) {
String[] values = args[k].split(";|,");
int x = args[k].split(";").length;
int y = args[k].split(";")[0].split(",").length;
Integer[][] array = new Integer[x][y];
int counter=0;
for (int i=0; i<x; i++) {
for (int j=0; j<y; j++) {
array[i][j] = Integer.parseInt(values[counter]);
counter++;
}
}
//Arrays contains all the 2d array created
arrays.add(array);
}
//Example to Show the result i.e. arg[0] is show
if(args[0].equalsIgnoreCase("show"))
for (Integer[][] integers : arrays) {
for (int i=0; i<integers.length; i++) {
for (int j=0; j<integers[0].length; j++) {
System.out.print(integers[i][j]+" ");
}
System.out.println();
}
System.out.println("******");
}
}
input
show 1,2;3,4 5,6;7,8
output
1 2
3 4
******
5 6
7 8
input for inpt with varible one 3*3 one 2*3 matrix
show 1,23,45;33,5,1;12,33,6 1,4,6;33,77,99
output
1 23 45
33 5 1
12 33 6
******
1 4 6
33 77 99
******
In the program arguments using a space splits it into two different arguments. What would probably be best for you is to change it to the format to:
1,2;0,3;3,4;3,4
Then
String[] firstMatrix = args[0].split(";");
System.out.print(Arrays.toString(firstMatrix));
Produces
[1,2, 0,3, 3,4, 3,4]
And doing
int[][] ints = new int[firstMatrix.length][2];
int[] intsInside;
for (int i = 0; i < firstMatrix.length; i++) {
intsInside = new int[2];
intsInside[0] = Integer.parseInt(firstMatrix[i].split(",")[0]);
intsInside[1] = Integer.parseInt(firstMatrix[i].split(",")[1]);
ints[i] = intsInside;
}
System.out.print("\n" + Arrays.deepToString(ints));
Produces
[[1, 2], [0, 3], [3, 4], [3, 4]]
NOTE: Values 0, 1, and 2 in certain places in the code should be replaced with dynamic values based on array lengths etc.
As you have provided arguments like "1,2;0,3 3,4;3,4", it seems you will have args[0] and args[1] as two-parameter for input but you have only shown args[0] in your example. Below is a modified version of your code which might give you hint for your solution
public static void main(String[] args) {
for (String tmpString : args) {
String[] firstmatrix = tmpString.split(";");
// Assuming that only two elements will be there splitter by `,`.
// If not the case, you have to add additional logic to dynamically get column length
String[][] rowNumbers = new String[firstmatrix.length][2];
for (int i = 0; i < firstmatrix.length; i++) {
rowNumbers[i] = firstmatrix[i].split(",");
}
}
}
You can try something like splitting the input by semicolon first in order to get the rows of the matrix and then split each row by comma in order to get the single values of a row.
The following example does exactly that:
public static void main(String[] args) {
System.out.println("Please enter the matrix values");
System.out.println("(values of a row delimited by comma, rows delimited by semicolon, example: 1,2;3,4 for a 2x2 matrix):\n");
// fire up a scanner and read the next line
try (Scanner sc = new Scanner(System.in)) {
String line = sc.nextLine();
// split the input by semicolon first in order to have the rows separated from each other
String[] rows = line.split(";");
// split the first row in order to get the amount of values for this row (and assume, the remaining rows have this size, too
int columnCount = rows[0].split(",").length;
// create the data structre for the result
int[][] result = new int[rows.length][columnCount];
// then go through all the rows
for (int r = 0; r < rows.length; r++) {
// split them by comma
String[] columns = rows[r].split(",");
// then iterate the column values,
for (int c = 0; c < columns.length; c++) {
// parse them to int, remove all whitespaces and put them into the result
result[r][c] = Integer.parseInt(columns[c].trim());
}
}
// then print the result using a separate static method
print(result);
}
}
The method that prints the matrix takes an int[][] as input and looks like this:
public static void print(int[][] arr) {
for (int r = 0; r < arr.length; r++) {
int[] row = arr[r];
for (int v = 0; v < row.length; v++) {
if (v < row.length - 1)
System.out.print(row[v] + " | ");
else
System.out.print(row[v]);
}
System.out.println();
if (r < arr.length - 1)
System.out.println("—————————————");
}
}
Executing this code and inputting the values 1,1,1,1;2,2,2,2;3,3,3,3;4,4,4,4 results in the output
1 | 1 | 1 | 1
—————————————
2 | 2 | 2 | 2
—————————————
3 | 3 | 3 | 3
—————————————
4 | 4 | 4 | 4
I tried the java8 stream way, with int[][] as result
String s = "1,2;0,3;3,4;3,4";
int[][] arr = Arrays.stream(s.split(";")).
map(ss -> Stream.of(ss.split(","))
.mapToInt(Integer::parseInt)
.toArray())
.toArray(int[][]::new);
With List<List<Integer>>, should be the same effect.
String s = "1,2;0,3;3,4;3,4";
List<List<Integer>> arr = Arrays.stream(s.split(";")).
map(ss -> Stream.of(ss.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList()))
.collect(Collectors.toList());
System.out.println(arr);
Hope it helps

How do I convert a String to an 2D Array of ints?

Currently I have a String called x that displays the following
100
000
000
How do I convert it into an nxn, int[][] array called board? The array contents should look like how its printed above. However, the array must be initialized depending on the rows / columns of the String. In the example above, it should be a 3x3 array.
I'm not sure how to start. The first problem I have is iterating through the String and counting how many "rows" / "columns" are in the String,
In addition to writing the contents in the correct order. Here is what I have attempted so far...
for (int i = 0; i < x.length(); i++)
{
char c = x.charAt(i);
board[i][] = c;
}
I assume that your string stored in Java looks like String str = "100\r\n000\r\n000";, then you can convert it to a 2D array as follows:
Code snippet
String str = "100\r\n000\r\n000";
System.out.println(str);
String[] str1dArray = str.split("\r\n");
String[][] str2dArray = new String[str1dArray.length][str1dArray[0].length()];
for (int i = 0; i < str1dArray.length; i++) {
str2dArray[i] = str1dArray[i].split("");
System.out.println(Arrays.toString(str2dArray[i]));
}
Console output
100
000
000
[1, 0, 0]
[0, 0, 0]
[0, 0, 0]
Updated
Following code snippet shows how to convert the string to a 2D integer array with Lambda expression (since Java 8).
int[][] str2dArray = new int[str1dArray.length][str1dArray[0].length()];
for (int i = 0; i < str1dArray.length; i++) {
str2dArray[i] = Arrays.stream(str1dArray[i].split("")).mapToInt(Integer::parseInt).toArray();
// This also works without using Lambda expression
/*
for (int j = 0; j < str1dArray[i].length(); j++) {
str2dArray[i][j] = Integer.parseInt(String.valueOf(str1dArray[i].charAt(j)));
}
*/
System.out.println(Arrays.toString(str2dArray[i]));
}
With your data you will have only the first row, you need more data.
String a = "100\n" +
"000\n" +
"000";
String matriz[][] = {a.split("\n")};

Is there a way to initialize a 2d array with other arrays?

I have been given a homework assignment as follows:
Read three sentences from the console application. Each sentence should not exceed 80 characters. Then, copy each character in each input sentence in a [3 x 80] character array.
The first sentence should be loaded into the first row in the reverse order of characters – for example, “mary had a little lamb” should be loaded into the array as “bmal elttil a dah yram”.
The second sentence should be loaded into the second row in the reverse order of words – for example, “mary had a little lamb” should be loaded into the array as “lamb little a had mary”.
The third sentence should be loaded into the third row where if the index of the array is divisible by 5, then the corresponding character is replaced by the letter ‘z’ – for example, “mary had a little lamb” should be loaded into the array as “mary zad azlittze lazb” – that is, characters in index
positions 5, 10, 15, and 20 were replaced by ‘z’. Note that an empty space is also a character, and that the index starts from position 0.
Now print the contents of the character array on the console.
The methods, return types, and parameters in the code below are all specified as required so I cannot change any of that information. I am having trouble initializing the 2d array. The instructions say that the sentences must be loaded into the array already reversed etc. but the parameters of the methods for doing this calls for strings. I assume that means I should read the lines as strings and then call the methods to modify them, then use toCharyArray to convert them before loading them into the 2d array. I don't understand how to initialize the 2D array with the values of the char arrays. Is there some kind of for loop I can use? Another issue is that no processing can be done inside of the main method but in the instructions there is no method that I can call to fill the array.
import java.util.regex.Pattern;
public class ReversedSentence {
public static String change5thPosition(String s){
char[] chars = s.toCharArray();
for (int i = 5; i < s.length(); i = i + 5) {
chars[i] = 'z';
}
String newString = new String(chars);
return newString;
}
public static String printChar2DArray(char[][] arr){
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 80; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
}
return null;
}
public static String reverseByCharacter(String s){
String reverse = new StringBuffer(s).reverse().toString();
return reverse;
}
public static String reverseByWord(String s){
Pattern pattern = Pattern.compile("\\s"); //splitting the string whenever there
String[] temp = pattern.split(s); // is whitespace and store in temp array.
String result = "";
for (int i = 0; i < temp.length; i++) {
if (i == temp.length - 1)
result = temp[i] + result;
else
result = " " + temp[i] + result;
}
return result;
}
public static String truncateSentence(String s){
if (s==null || s.length() <= 80)
return s;
int space = s.lastIndexOf(' ', 80);
if (space < 0)
return s.substring(0, 80);
return s;
}
public static void main(String[] args) {
String sentence1 = ("No one was available, so I went to the movies alone.");
String sentence2 = "Ever since I started working out, I am so tired.";
String sentence3 = "I have two dogs and they are both equally cute.";
char[][] arr = new char[3][80];
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
printChar2DArray(arr);
}
}
The error I am getting is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 52 out of bounds for length 52
at ReversedSentence.printChar2DArray(ReversedSentence.java:20)
at ReversedSentence.main(ReversedSentence.java:71)
.enola seivom eht ot tnew I os ,elbaliava saw eno oN
The problem is that in your printChar2DArray method you assume that every array has the length of 80, but that's actually not the case here. In Java, a 2D array is just an array of arrays. So, when you have this: char[][] arr = new char[3][80], you are creating an array of 3 arrays, and each of these arrays has the length of 80 characters. That may seem ok, but in the next lines you reinitialize the 3 arrays with something different entirely.
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
Now none of these arrays has the length of 80. Each of them has the length of the respective string.
You can solve this in 2 ways (depending on how constrained your task actually is).
First, you can copy the string into arrays, instead of assigning the arrays to the results of the toCharArray method. You can achieve this with a simple loop, but I wouldn't recommend this approach, because you will end up with arrays of 80 characters, even if the strings contain less.
String firstSentence = reverseByCharacter(sentence1);
for (int i = 0; i < firstSentence.length(); i++) {
arr[0][i] = firstSentence.charAt(i);
}
Or:
char[] firstSentence = reverseByCharacter(sentence1).toCharArray();
for (int i = 0; i < firstSentence.length; i++) {
arr[0][i] = firstSentence[i];
}
Second, you can drop the assumption of the arrays' lengths in the printChar2DArray method. I recommend this approach, because it makes you code much more flexible. Your printChar2DArray method will then look like this:
public static String printChar2DArray(char[][] arr){
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y < arr[x].length; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
}
return null;
}
You can see that I've substituted numbers with the length field, which can be accessed for any array.
Also, this way you don't need to initialize the inner arrays, because you reinitialize them in the next lines anyway.
char[][] arr = new char[3][];
arr[0] = reverseByCharacter(sentence1).toCharArray();
arr[1] = reverseByWord(sentence2).toCharArray();
arr[2] = change5thPosition(sentence3).toCharArray();
But this approach may not be suitable for your task, because then the sentences could be of any length, and they wouldn't be constained to 80 characters max.
UPDATE - To answer the question in the comment
To print a newline character you can use System.out.println() without parameters. It's better than putting the newline character into the arrays because it's not a logical part of the sentences.
So your for-loop in the printChar2DArray would look like this:
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 80; y++) {
// just a print so it does not make new lines for every char
System.out.print(arr[x][y]);
}
System.out.println();
}

JAVA 2D String array column numbers

I have a CSV file which I have to read to a 2D string array (it must be a 2D array)
However it has different column number, like:
One, two, three, four, five
1,2,3,4
So I want to read those into an array. I split it everything is good, however I don't know how not to fill the missing columns with NULLs.
The previous example is:
0: one,two,three,four,five (length 5)
1: 1,2,3,4,null (length 5)
However I want the next row's length to be 4 and not 5 without null.
Is this possible?
This is where I've got so far (I know it's bad):
public static void read(Scanner sc) {
ArrayList<String> temp = new ArrayList<>();
while(sc.hasNextLine()) {
temp.add(sc.nextLine().replace(" ", ""));
}
String[] row = temp.get(0).split(",");
data = new String[temp.size()][row.length];
for (int i = 0; i < temp.size(); ++i) {
String[] t = temp.get(i).split(",");
for (int j = 0; j < t.length; ++j) {
data[i][j] = t[j];
}
}
}
Sounds like you want a non-rectangular 2-dimensional array. You'll want to avoid defining the second dimension on your 2D array. Here's an example:
final Path path = FileSystems.getDefault().getPath("src/main/resources/csvfile");
final List<String> lines = Files.readAllLines(path);
final String[][] arrays = new String[lines.size()][];
for (int i = 0; i < lines.size(); i++) {
arrays[i] = lines.get(i).split(",");
}
All lines are read into a List so that we know the first dimension of the 2D array. The second dimension for each row is determined by the result of the split operation.

Categories

Resources