Combination of subarrays - java

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

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]

Modifying a 2D array using a nested for loop

I am trying to print out the 'middle' of the 2D array (a). For example, for given arrays in my code, I would like to print:
[3,4,5,6]
[4,5,6,7]
However I was only able to print out the 'middle' values. I would like to modify the 2D array (a) in the method inner and print it in main instead, and not use System.out.println in the nested for loop. How would I go about doing this?
Here is my code:
public static int[][] inner(int[][] a) {
int rowL = a.length - 1;
int colL = a[1].length - 1;
for (int row = 1; row < rowL; row++) {
for (int col = 1; col < colL; col++) {
//System.out.print(a[row][col]);
a = new int[row][col];
}
System.out.println();
}
return a;
}
public static void main(String[] args) {
int[][] a = {
{1, 2, 3, 4, 5, 6},
{2, 3, 4, 5, 6, 7},
{3, 4, 5, 6, 7, 8},
{4, 5, 6, 7, 8, 9}};
for (int[] row : a) {
System.out.println(Arrays.toString(row));
}
System.out.println();
for (int[] row : inner(a)) {
System.out.println(Arrays.toString(row));
}
}
Create a new array outside the loop and then fill that array inside the loop by translating the indices between the two arrays:
public static int[][] inner (int[][] a) {
int rowL = a.length - 1;
int colL = a[1].length -1;
int[][] ret = new int[rowL - 1][colL - 1];
for (int row = 1; row < rowL; row++) {
for (int col = 1; col < colL ; col++) {
ret[row - 1][col - 1] = a[row][col];
}
}
return ret;
}
If you just want to print the middle values (my definition for this code example is: middle = full array minus first and last element), you can make use of a StringBuilder:
public static void main(String[] args) {
int[][] a = {
{ 1, 2, 3, 4, 5, 6 },
{ 2, 3, 4, 5, 6, 7 },
{ 3, 4, 5, 6, 7, 8 },
{ 4, 5, 6, 7, 8, 9 }
};
for (int[] b : a) {
// create a String output for each inner array
StringBuilder outputBuilder = new StringBuilder();
// append an introducing bracket
outputBuilder.append("[");
// make the values to be printed ignore the first and last element
for (int i = 1; i < b.length - 1; i++) {
if (i < b.length - 2) {
/*
* append a comma plus whitespace
* if the element is not the last one to be printed
*/
outputBuilder.append(b[i]).append(", ");
} else {
// just append the last one without trailing comma plus whitespace
outputBuilder.append(b[i]);
}
}
// append a closing bracket
outputBuilder.append("]");
// print the result
System.out.println(outputBuilder.toString());
}
}
The output will be
[2, 3, 4, 5]
[3, 4, 5, 6]
[4, 5, 6, 7]
[5, 6, 7, 8]
You can use Arrays.stream(T[],int,int) method to iterate over a given range of an array:
int[][] arr = {
{1, 2, 3, 4, 5, 6},
{2, 3, 4, 5, 6, 7},
{3, 4, 5, 6, 7, 8},
{4, 5, 6, 7, 8, 9}};
int[][] middle = Arrays.stream(arr, 1, arr.length - 1)
.map(row -> Arrays.stream(row, 1, row.length - 1)
.toArray())
.toArray(int[][]::new);
// output
Arrays.stream(middle).map(Arrays::toString).forEach(System.out::println);
[3, 4, 5, 6]
[4, 5, 6, 7]

My selection sorting code is failing on one index

I'm having great issues with my selection sort code can anyone explain to me where i'm going wrong?
this code works for the most part however when it gets to the 4/5th round it false to sort the 5 as the next lowest instead going to the 6 in the array.
this is what my output looks like. As you can see the 5 is clearly in the wrong place.
any help understand why this is would be great thank you.
[1, 9, 4, 10, 5, 3, 6, 2, 8, 7]
[1, 2, 9, 10, 5, 3, 6, 4, 8, 7]
[1, 2, 3, 10, 9, 5, 6, 4, 8, 7]
[1, 2, 3, 4, 10, 9, 5, 6, 8, 7]
[1, 2, 3, 4, 6, 10, 9, 5, 8, 7]
[1, 2, 3, 4, 6, 5, 10, 9, 8, 7]
[1, 2, 3, 4, 6, 5, 7, 10, 9, 8]
[1, 2, 3, 4, 6, 5, 7, 8, 10, 9]
[1, 2, 3, 4, 6, 5, 7, 8, 9, 10]
-
public class Selection {
void findSmallestNumberIndex(int[] numbers, int index) {
//int[] numbers = {4, 9, 2, 10, 5, 3, 6, 1, 8, 7};
int n = numbers.length;
int min_idx = index; //4
for (int j = index + 1; j < n; j++) {
if (numbers[j] < numbers[min_idx]) {
min_idx = j;
}
int temp = numbers[min_idx];
numbers[min_idx] = numbers[index];
numbers[index] = temp;
}
}
public static void main(String[] args) {
int[] numbers = {4,9,2,10,5,3,6,1,8,7};
int NumLen = numbers.length;
int[] sortedNum = new int[NumLen];
int index;
index = 0;
Selection OB = new Selection();
do {
OB.findSmallestNumberIndex(numbers, index);
index++;
System.out.println(Arrays.toString(numbers));
} while (index != (NumLen - 1));
}
}
Move the logic to adjust array outside the for loop, here's how it should look:
void findSmallestNumberIndex(int[] numbers, int index) {
//int[] numbers = {4, 9, 2, 10, 5, 3, 6, 1, 8, 7};
int n = numbers.length;
int min_idx = index; //4
for (int j = index + 1; j < n; j++) {
if (numbers[j] < numbers[min_idx]) {
min_idx = j;
}
}
int temp = numbers[min_idx];
numbers[min_idx] = numbers[index];
numbers[index] = temp;
}

Convert String into a two dimensional array

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.

Large arraylist, finding the product of certain amount of elements

I have an array list which contains the numbers below, and what i am trying to do is find the product of every 16 numbers.
try {
for (int z = 0; z < 1000; z++) {
System.out.println(list.subList(z, z + 16));
the above prints this
[7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 0, 6, 2]
[3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 0, 6, 2, 4]
[1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 0, 6, 2, 4, 9]
[6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 0, 6, 2, 4, 9, 1]
etc......
my solution was to put every line above in to an array and find the product of that array.However i am stuck, was wondieering if anyone can provide me a few pointers on about how to take a hit at this
list.subList(z, z + 16);
for(int i = 0; i < list.subList(z, z+16).size();i++){
Ar[i] = list.get(z);
}
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
If you had a ArrayList of ArrayList then you could do
ArrayList <ArrayList> listofList = new ArrayList ();
for (int z = 0; z < 1000; z = z + 16) {
int endpoint = z + 16; // check to see not bigger than 1000
ArrayList thisList = list.subList(z, endpoint);
listOfList.add (thisList);
System.out.println(thisList);
}
But there again you may want to just add up as you go.
ArrayList thisList = list.subList(z, endpoint);
int prod = 1;
for (int x : thisList) {
prod *= x;
}
If you look at the printout that you are showing, you will that it is just moving one number each time - not what you want.
This is the solution I came up with. Instead of printing out the answer, you coudl add it to an array or something and use it later. Fyi I subbed the zeroes for 1's so I knew it was working.
public static void main(String[] args) throws Exception
{
int[] arr = {7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 1, 6, 2, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 1, 6, 2, 4, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 1, 6, 2, 4, 9};
int counter = 0;
int product = 1;
for (int i : arr)
{
if (counter < 16)
{
product *= i;
counter++;
}
if (counter >= 16)
{
System.out.println(product);
product = 1;
counter = 0;
}
}
}
This is what printed (again I subbed the zeroes for ones):
60011280
34292160
102876480

Categories