Convert String into a two dimensional array - java

I try to convert this string
s=[[4, 2, 2, 4], [3, 4, 5, 6], [6, 7, 8, 9], [3, 2, 1, 4]]
into a two dimensional array like this
{4, 2, 2, 4},
{3, 4, 5, 6},
{6, 7, 8,9},
{3, 2, 1, 4}
by use this code
int e=s.replaceAll("\\[", "").replaceAll(" ","").replaceAll("],","]").length();
String[] rows1 = s.replaceAll("\\[", "").replaceAll(" ","").replaceAll("],","]").substring(0, e-2).split("]");
String[][] matrix1 = new String[4][4];
int r1 = 0;
for (String row1 : rows1) {
matrix[r1++] = row1.split(",");
}
System.out.println(Arrays.deepToString(matrix1));
But is have problem like this
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at test.main(test.java:94)
Can you help me find a solution?

I think this code will help you. Read the all comments carefully.
String s="[[4, 2, 2, 4], [3, 4, 5, 6], [6, 7, 8, 9], [3, 2, 1, 4]]";
s=s.replace("[","");//replacing all [ to ""
s=s.substring(0,s.length()-2);//ignoring last two ]]
String s1[]=s.split("],");//separating all by "],"
String my_matrics[][] = new String[s1.length][s1.length];//declaring two dimensional matrix for input
for(int i=0;i<s1.length;i++){
s1[i]=s1[i].trim();//ignoring all extra space if the string s1[i] has
String single_int[]=s1[i].split(", ");//separating integers by ", "
for(int j=0;j<single_int.length;j++){
my_matrics[i][j]=single_int[j];//adding single values
}
}
//printing result
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
System.out.print(my_matrics[i][j]+" ");
}
System.out.println("");
}
[[4, 2, 2, 4], [3, 4, 5, 6], [6, 7, 8, 9], [3, 2, 1, 4]]
Logic:
1) replacing all [ to "" now I have-> 4, 2, 2, 4], 3, 4, 5, 6], 6, 7, 8, 9], 3, 2, 1, 4]]
2) Separating all by "]," now I have->
A) 4, 2, 2, 4
B) 3, 4, 5, 6
c) 6, 7, 8, 9
d) 3, 2, 1, 4
3) Separating A B C D by ", " now I have->
A) a) 4 b) 2 c) 2 d) 4
B) a) 3 b) 4 c) 5 d) 6
c) a) 6 b) 7 c) 8 d) 9
d) a) 3 b) 2 c) 1 d) 4

Solution using Java streams:
String[][] arr = Arrays.stream(str.substring(2, str.length() - 2).split("\\],\\["))
.map(e -> Arrays.stream(e.split("\\s*,\\s*"))
.toArray(String[]::new)).toArray(String[][]::new);

Try this...
String s="[[4, 2, 2, 4], [3, 4, 5, 6], [6, 7, 8, 9], [3, 2, 1, 4]]";
// Split on this delimiter
String[] rows = s.split("], \\[");
for (int i = 0; i < rows.length; i++) {
// Remove any beginning and ending braces and any white spaces
rows[i] = rows[i].replace("[[", "").replace("]]", "").replaceAll(" ", "");
}
// Get the number of columns in a row
int numberOfColumns = rows[0].split(",").length;
// Setup your matrix
String[][] matrix = new String[rows.length][numberOfColumns];
// Populate your matrix
for (int i = 0; i < rows.length; i++) {
matrix[i] = rows[i].split(",");
}
// Display your matrix
System.out.println(Arrays.deepToString(matrix));
Results:

This just doesn't add the comma's at the end of the line:
String s = "[[4, 2, 2, 4], [3, 4, 5, 6], [6, 7, 8, 9], [3, 2, 1, 4]]";
for (String l: s.split("\\]\\s*,\\s*\\[")) {
l = l.replaceAll("\\[", "").replaceAll("\\]", "");
System.out.println("{" + l + "}");
}

Assuming that the input string will always be in that format, with 4 integers between each bracket, I think the best way to do it would simply be to use a Scanner object and it's nextInt() method which will ignore the brackets and comma's and just find the numbers. Then put them into a 2d array like how you would with a loop.
It kinda gets rid of all the fun you were having with removing the brackets though, so it's not really better in terms of making an exercise out of this.

Related

how to add values in an array from last value to first

How can I add the values in the arrNumbers that exceed 6 to add to a new array starting from the last value and ending at the first.
This is what I have written, but does not produce the right output.
int[] arrNumbers = new int[] { 1, 2, 3, 4, 5, 6, 1, 2 };
int[] newArrNumbers = new int[6];
for(int i = 0; i < arrNumbers.length ; i++){
newArrNumbers[i % 6] += arrNumbers[i];
}
The actual output:
newArrNumbers = [2, 4, 3, 4, 5, 6]
However, I want the output to ADD to the LAST VALUE in the arrNumbers, going from right to left, not left to right. So result should be:
newArrNumbers = [1, 2, 3, 4, 7, 7]
Try this.
int[] arrNumbers = new int[] { 1, 2, 3, 4, 5, 6, 1, 2 };
int[] newArrNumbers = new int[6];
for(int i = 0; i < arrNumbers.length ; i++){
newArrNumbers[i < 6 ? i : (6 - (i % 6) - 1)] += arrNumbers[i];
}
System.out.println(Arrays.toString(newArrNumbers));
output:
[1, 2, 3, 4, 7, 7]

Combination of subarrays

Not sure if this has been asked already but I'm having trouble printing combinations of subarrays.
Given say
int[][] x= {{1,2},{3,4,5},{6,7}};
print all valid combinations by choosing one int from each subarray.
some valid outputs are:
1,3,6
1,3,7
1,4,6
1,4,7
..
... etc
SO far my code looks like
public static void main(String args[]) {
int[][] x= {{1,2},{3,4,5},{6,7}};
for(int i = 0; i < x.length; i++){
for (int j = 0; j < 3; j++){
for (int k = 0; k < 2; k++){
System.out.println(x[0][i]+" " + x[1][j] +" "+ x[2][k]);
}
}
My code is throwing an exeption indexoutofbounds. I'm not sure where I'm going out of bounds. I know its the naive solution and brute force and theres prob a better way to solve it but this solution is the first that came across my mind.
Instead of doing i < x.length, try i < x[0].length The length of x is 3 and that of the first element is 2. Hence, the out of bounds exception. Also, it might be a good idea to get x[1].length and x[2].length instead of hard coding 3 and 2.
Try:
public class MyClass {
public static void main(String args[]) {
int[][] x= {{1,2},{3,4,5},{6,7}};
for (int i = 0; i < x[0].length; i++){
for (int j = 0; j < x[1].length; j++){
for(int k = 0; k < x[2].length; k++){
System.out.println(x[0][i] + " " + x[1][j] + " " + x[2][k]);
}
}
}
}
}
Looking for something complex written in Java 8? Here it is:
package com.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ArrayPrint {
#SuppressWarnings("resource")
public static void main(String args[]) {
int[][] x = { { 1, 2 }, { 3, 4, 5 }, { 6, 7 } };
Stream<List<Integer>> inputs = null;
for (int[] set : x) {
List<Integer> list = new ArrayList<Integer>();
Collections.addAll(list, Arrays.stream(set).boxed().toArray(Integer[]::new));
if (inputs == null) {
inputs = Stream.of(list);
} else {
inputs = Stream.concat(inputs, Stream.of(list));
}
}
Stream<List<List<Integer>>> listified = inputs.filter(Objects::nonNull).filter(input -> !input.isEmpty())
.map(l -> l.stream().map(o -> new ArrayList<>(Arrays.asList(o))).collect(Collectors.toList()));
List<List<Integer>> combinations = listified.reduce((input1, input2) -> {
List<List<Integer>> merged = new ArrayList<>();
input1.forEach(permutation1 -> input2.forEach(permutation2 -> {
List<Integer> combination = new ArrayList<>();
combination.addAll(permutation1);
combination.addAll(permutation2);
merged.add(combination);
}));
return merged;
}).orElse(null);
combinations.forEach(System.out::println);
}
}
Output:
[1, 3, 6]
[1, 3, 7]
[1, 4, 6]
[1, 4, 7]
[1, 5, 6]
[1, 5, 7]
[2, 3, 6]
[2, 3, 7]
[2, 4, 6]
[2, 4, 7]
[2, 5, 6]
[2, 5, 7]
With int[][] x = { { 1, 2 }, { 3, 4, 5 }, { 6, 7 }, { 8, 9, 10 } };, Output:
[1, 3, 6, 8]
[1, 3, 6, 9]
[1, 3, 6, 10]
[1, 3, 7, 8]
[1, 3, 7, 9]
[1, 3, 7, 10]
[1, 4, 6, 8]
[1, 4, 6, 9]
[1, 4, 6, 10]
[1, 4, 7, 8]
[1, 4, 7, 9]
[1, 4, 7, 10]
[1, 5, 6, 8]
[1, 5, 6, 9]
[1, 5, 6, 10]
[1, 5, 7, 8]
[1, 5, 7, 9]
[1, 5, 7, 10]
[2, 3, 6, 8]
[2, 3, 6, 9]
[2, 3, 6, 10]
[2, 3, 7, 8]
[2, 3, 7, 9]
[2, 3, 7, 10]
[2, 4, 6, 8]
[2, 4, 6, 9]
[2, 4, 6, 10]
[2, 4, 7, 8]
[2, 4, 7, 9]
[2, 4, 7, 10]
[2, 5, 6, 8]
[2, 5, 6, 9]
[2, 5, 6, 10]
[2, 5, 7, 8]
[2, 5, 7, 9]
[2, 5, 7, 10]
Thus, this code can handle any two dimensional integer array.
Regarding my suggestion from the comments try this code and look at the changes to each for loop. Instead of iterating over predetermined size like for(int k = 0; k < 2; k++) We instead iterate based on the size of the array as follows for(int k = 0; k < x[1].length; k++)
public static void main(String args[]) {
int[][] x = { { 1, 2, 3}, { 3, 4, 5 }, { 6, 7 } };
for (int j = 0; j < x[0].length; j++) {
for (int k = 0; k < x[1].length; k++) {
for (int l = 0; l < x[2].length; l++) {
System.out.println(x[0][j] + " " + x[1][k] + " " + x[2][l]);
}
}
}
}
As long as your outer array only contains three arrays you can do as shown. Otherwise you will need to be a bit more sophisticated with you loops and not hardcode the specific index like for(int k = 0; k < x[0].length; k++) Here we are directly coding index 0.
Hope this helps.
You could always declare an array of objects and cast to the data-type of your choice like this.
public class PrintArray{
public static void main(String[] args){
Object[][] myArray = {{1, 2, 3},
{4, 5, null},
{7, 8, null}};
for(int x = 0; x < myArray.length; x++){
for(int y = 0; y < 3; y++){
if(myArray[x][y] != null){
System.out.print((int)myArray[x][y]);
}
}
System.out.println();
}
}
}
I hope this helps

Why does my insertion sort algorithm only work with single digit integers?

I've wrote a simple insertion sort algorithm for fun. It appears to be working just fine with one problem, it only works when all items in the array (the thing its trying to sort) are single digit integers. If an element is a multi-digit integer, it sorts everything up to that integer, then stops and throws an IndexOutOfBoundsException.
Note: Just so you understand the source code, the way my program works is like this: I pass the InsertionSort class a primative int array in construction. I then convert that to the ArrayList list. I know that the ArrayList list has the correct values copied over because I print it out and it matches up.
Example Runs:
Working:
{ 9, 2, 8, 5, 1, 6, 6, 7, 1}; //works perfectly ->
Unsorted List: [9, 2, 8, 5, 1, 6, 6, 7, 1]
Step 1: [9]
Step 2: [2, 9]
Step 3: [2, 8, 9]
Step 4: [2, 5, 8, 9]
Step 5: [1, 2, 5, 8, 9]
Step 6: [1, 2, 5, 6, 8, 9]
Step 7: [1, 2, 5, 6, 6, 8, 9]
Step 8: [1, 2, 5, 6, 6, 7, 8, 9]
Step 9: [1, 1, 2, 5, 6, 6, 7, 8, 9]
Sorted List: [1, 1, 2, 5, 6, 6, 7, 8, 9]
Not Working:
{ 9, 2, 8, 5, 1, 6, 6, 7, 1, 22, 823, 30, 244, 45, 5}; //doesn't work ->
Unsorted List: [9, 2, 8, 5, 1, 6, 6, 7, 1, 22, 823, 30, 244, 45, 5]
Step 1: [9]
Step 2: [2, 9]
Step 3: [2, 8, 9]
Step 4: [2, 5, 8, 9]
Step 5: [1, 2, 5, 8, 9]
Step 6: [1, 2, 5, 6, 8, 9]
Step 7: [1, 2, 5, 6, 6, 8, 9]
Step 8: [1, 2, 5, 6, 6, 7, 8, 9]
Step 9: [1, 1, 2, 5, 6, 6, 7, 8, 9]
java.lang.IndexOutOfBoundsException: Index: 9, Size: 9
Sorted List: [1, 1, 2, 5, 6, 6, 7, 8, 9]
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at InsertionSort.sort(InsertionSort.java:41)
at Executer.main(Executer.java:7)
Here is the relevant sorting code:
static ArrayList<Integer> list = new<Integer> ArrayList();
static ArrayList<Integer> list2 = new<Integer> ArrayList();
public static int[] sort() {
int s = 0;
System.out.println("Unsorted List: " + list.toString());
try {
for (int i = 0; i < list.size(); i++) {
s++;
if (i == 0) {
list2.add(list.get(i));
System.out.println("Step " + s + ": " + list2.toString());
continue;
} else {
int z = 0;
while (list2.get(z) < list.get(i)) {
z++;
}
list2.add(z, list.get(i));
}
System.out.println("Step " + s + ": " + list2.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Sorted List: " + list2.toString());
return toPrimative(list.toArray(new Integer[list.size()]));
}
It has nothing to do with single or multi digit numbers, in first example you were just lucky to have the biggest number as a first element in a list. There is an obvious mistake when you're choosing a position for the next element:
int z = 0;
while (list2.get(z) < list.get(i)) {
z++;
}
You increment index but don't do bounds check, so when it comes to number 22 you get an exception. The correct one would be
while (list2.get(z) < list.get(i) && z <= list2.size())
Mind debug. Problem is here:
while (list2.get(z) < list.get(i)) {
z++;
}
z exceeds list2 count if new value is the biggest.
First value 9 in small numbers example hid this problem.
I hope that solution is clear enough

Matrix manipulation (rotation/rolling)

I have this 3x3 matrix:
{
[1,2,3],
[4,5,6],
[7,8,9]
}
Suppose that if I send two parameters m and n, this matrix must move m and n positions (m positive / move right or negative move left) and (n positive / move down or n negative move up). For the sample if I send m = 1 , n = 0:
{
[3, 1, 2],
[6, 4, 5],
[9, 7, 8]
}
Is there some kind of method to do this? Or is it just 'hard handwork'?
If you are prepared to use List<List<Integer>> instead of int[][] you can use Collections.rotate(List list,int distance).
private void rotate(List<List<Integer>> matrix, int m, int n) {
for (List<Integer> row : matrix) {
Collections.rotate(row, m);
}
Collections.rotate(matrix, n);
}
public void test() {
int[][] m = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
List<List<Integer>> matrix = new ArrayList<>();
for (int[] r : m) {
List<Integer> row = new ArrayList<>();
for (int v : r) {
row.add(v);
}
matrix.add(row);
}
System.out.println("Before: " + matrix);
rotate(matrix, 1, 2);
System.out.println("After: " + matrix);
}
Prints:
Before: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
After: [[3, 1, 2], [6, 4, 5], [9, 7, 8]]
which is slightly different from what you were expecting but it looks like it makes sense.

bidimensional arraylists and inputting another array into them through a loop

I am trying to make an arraylist of which are essentially the rows of secondArr (which is a bidimensional arraylist). the problem is that when my cScore.size() == 7 (or equal to secondArr.size(), it does not get added to allScore, instead at the end all (in this case 21, asmyArr.size()=3, and secondArr.size()=7. values are added to one index, does anyone know why this is happening? the code seems to be so simple yet it is failing me. So in the end I would want a arraylist of 3 columns and 7 rows (but in this case just 1 column and 7 rows, and once I get this to work then I will add the rest.)
My code is as follows (this is just a small tidbit):
int rowsNum = allScores.size();
int colsNum = allScores.get(0).size();
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(colsNum);
for (int rowIdx = 0; rowIdx < colsNum; rowIdx++) {
ArrayList<Integer> rows = new ArrayList<Integer>(rowsNum);
for (int colIdx = 0; colIdx < rowsNum; colIdx++) {
rows.add(allScores.get(colIdx).get(rowIdx)); {
}
result.add(rows);
}
//using the syntax prov. by msi....
the original array allScores is:
[[2, 1, 3], [3, 1, 2], [2, 1, 3], [3, 1, 2],[ 2, 1, 3], [3, 1, 2], [1, 2, 3]]
when it is transposed with this it reeesults in
[[2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1], [2, 3, 2, 3, 2, 3, 1]]
candScore.add(secondArr.get(j).get(k));
shouldn't that be:
cScore.add(secondArr.get(j).get(k));
Plus I have the feeling that your two nested loops should be the other way around.
for (int j=0; j< secondArr.size(); j++){
for (int k=0; k< myArr.size(); k++) {
I am not sure where your bug lies, but my guess is:
maybe the order of your two-dimensional array (i.e. it is 7 x 3 instead of 7 x 3)
do you really need that many ArrayLists to implement your algorithm
improve your code quality, e.g. by avoiding magic numbers (7 instead of size()), using extended for loops and assertions will drastically ease finding the bug.
I belive this is what you want. This code transposes 2d arraylists so column will become row, and row
will become column after transposition.
Example:
[[1 2 3], [4 5 6], [7 8 9]] -> [[1 4 7], [2 5 8], [3 6 9]]
this code assumes that all rows/columns have the same length.
// arr2d is ArrayList<ArrayList<Integer>>
int rowsNum = arr2d.size();
int colsNum = arr2d.get(0).size();
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(colsNum);
for (int rowIdx = 0; rowIdx < colsNum; rowIdx++) {
ArrayList<Integer> rows = new ArrayList<Integer>(rowsNum);
for (int colIdx = 0; colIdx < rowsNum; colIdx++) {
rows.add(arr2d.get(colIdx).get(rowIdx));
}
result.add(rows);
}
... edit (answer to 1st comment)
I don't see your point. Check:
ArrayList<ArrayList<Integer>> arr2d = new ArrayList<ArrayList<Integer>>();
arr2d.add(new ArrayList<Integer>(2));
arr2d.add(new ArrayList<Integer>(2));
arr2d.add(new ArrayList<Integer>(2));
arr2d.get(0).add(1);
arr2d.get(0).add(2);
arr2d.get(1).add(3);
arr2d.get(1).add(4);
arr2d.get(2).add(5);
arr2d.get(2).add(6);
above gives you: [[1, 2], [3, 4], [5, 6]] -> [[1, 3, 5], [2, 4, 6]] transformation. There are no copies of rows or columns you are talking about.

Categories