Create a matrix from a string - java

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.

Related

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.

Function with Short data type is running way to different than with double

I have two functions which I thought to be quit simular despite from they are using different data types:
public double[] getdoubleArray(){
final String[] myStringArray = oldArray[0].split(",");
double[] d = new double[myStringArray.length];
for(int i = 0; i < d.length -1; i++){
d[i] = Double.parseDouble(myStringArray[i]);
}
return d;
}
this works as it should.
public short[] getshortArray(){
final String[] myStringArray = oldArray[1].split(",");
short[] s = new short[myStringArray.length];
for(int i = 0; i < s.length -1; i++){
s[i] = Short.parseShort(myStringArray[i]);
}
return s;
}
this function is called shortly after the one above and every time it is in the loop with i = 1 it is being interrupted by an other Thread or the ZygoteInit class. but when I change the data type to double then it works fine.(Exept for the fact that I neet a short array)
Can anyone explain this or has a sulution?
EDIT
1. I don´t get an exeption. When i debug I usually end up some where between the lines where isn´t actual code.
The data in the string can´t be the problem since I copied it form a short array that worked. (the string in oldArray[1] is this: "0, 1, 2, 0, 2, 3, 4")
The problem is spaces in your input string. Double.parseDouble tolerates spaces, while Short.parseShort throws NumberFormatException when they are encountered. Try Short.parseShort(myStringArray[i].trim()).

Convert string into two dimensional string array in 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]]"

Categories

Resources