I have three 2*2 matrices. I need to find all the possible sequences
from them. But the condition is I cannot take more than one value from
each of the matrices. Suppose: matrix1[][]= {1,2,3,4} matrix2[][]=
{5,6,7,8} matrxi3[][]= {9,10,11,12} the subsets can be (1,5,9),
(4,5,11), (3,7,12)...and so on. But not (1,2,7) or (4,10,12). The
condition is, value cannot come from the same matrix. I tried to
arrange the values of the 2*2 matrices in a 1-D array and then tried
to apply recursive solution but cannot find the proper condition. Here
is the code to find usual subsets from a given array:
class Combination {
static void combinationUtil(int arr[], int data[], int start,
int end, int index, int r)
{
// Current combination is ready to be printed, print it
if (index == r)
{
for (int j=0; j<r; j++)
System.out.print(data[j]+" ");
System.out.println("");
return;
}
for (int i=start; i<=end && end-i+1 >= r-index; i++)
{
data[index] = arr[i];
combinationUtil(arr, data, i+1, end, index+1, r);
}
}
static void printCombination(int arr[], int n, int r)
{
int data[]=new int[r];
combinationUtil(arr, data, 0, n-1, 0, r);
}
/*Driver function to check for above function*/
public static void main (String[] args) {
int arr[] = {1,2,3,4,5,6,7,8,9,10,11,12};
int r = 3;
int n = arr.length;
printCombination(arr, n, r);
}
}
the requirement to find subsequences of any length was not really clear from you question. Try this out:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Difficult {
public static void main(String[] argg) {
// inputs: define your matrixes as arrays here
int[][] m1 = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
// print input data
System.out.print("input: [");
for (int length = 0; length < m1.length; length++) {
System.out.print(Arrays.toString(m1[length]));
if (length < m1.length - 1) {
System.out.print(",");
}
}
System.out.println("]");
for (int i = 2; i <= m1.length; i++) {
// find and print subsets starts from 2
print(i, findSubsets(i, m1.length), m1);
}
}
static List<List<Integer>> findSubsets(int grade, int base) {
List<List<Integer>> result = new ArrayList<>();
if (grade > base) return result;
int max = base - 1;
int[] counters = new int[grade];
// init counters
for (int i = 0; i < grade; i++) {
counters[i] = i;
}
do {
addSubset(counters, result);
} while (increment(counters, max));
return result;
}
static void addSubset(int[] counters, List<List<Integer>> result) {
List<Integer> subset = new ArrayList<>();
for (int i : counters) {
subset.add(i);
}
result.add(subset);
}
// increment to next combination and check for stop
static boolean increment(int[] counters, int max) {
boolean result = false;
for (int i = counters.length - 1; i >= 0; i--) {
// last counter can be incremented until max
// before last counter until max-1 and so on
int counterMax = max - (counters.length - 1 - i);
if (counters[i] < counterMax) {
counters[i]++;
int counterValue = counters[i];
// reset all following counter after the current, if there are any
for (int j = i + 1; j < counters.length - 1; j++) {
counters[j] = (++counterValue);
}
result = true;
break;
}
}
return result;
}
static void print(int i, List<List<Integer>> sets, int[][] input) {
//print index combinations
System.out.println("index combinations, size " + i + " : " + sets);
//print element combinations
System.out.print("combinations, size " + i + ": [");
for (List<Integer> set : sets) {
int[][] subset = new int[set.size()][];
int count = 0;
for (int index : set) {
subset[count] = input[index];
count++;
}
print(subset);
}
System.out.println("]");
}
static void print(int[][] matrix) {
// initialize position
int[] positions = new int[matrix.length];
for (int i = 0; i < positions.length; i++) {
positions[i] = 0;
}
boolean end;
do {
//print out current matrix position
String combination = "";
for (int i = 0; i < positions.length; i++) {
if (combination.length() != 0) {
combination += ", ";
}
combination += matrix[i][positions[i]];
}
System.out.print("[" + combination + "]");
end = true;
// increment and set end
for (int i = positions.length - 1; i >= 0; i--) {
int value = positions[i];
if (value < matrix[i].length - 1) {
positions[i]++;
// reset position in every following row (if there is any) to zero
for (int j = i + 1; j < positions.length; j++) {
positions[j] = 0;
}
end = false;
break;
}
}
if (!end) {
System.out.print(",");
}
} while (!end);
}
}
this code is able to find combinations of every possible length from given input. it generates following output:
input: [[1, 2, 3, 4],[5, 6, 7, 8],[9, 10, 11, 12]]
index combinations, size 2 : [[0, 1], [0, 2], [1, 2]]
combinations, size 2: [[1, 5],[1, 6],[1, 7],[1, 8],[2, 5],[2, 6],[2, 7],[2, 8],[3, 5],[3, 6],[3, 7],[3, 8],[4, 5],[4, 6],[4, 7],[4, 8][1, 9],[1, 10],[1, 11],[1, 12],[2, 9],[2, 10],[2, 11],[2, 12],[3, 9],[3, 10],[3, 11],[3, 12],[4, 9],[4, 10],[4, 11],[4, 12][5, 9],[5, 10],[5, 11],[5, 12],[6, 9],[6, 10],[6, 11],[6, 12],[7, 9],[7, 10],[7, 11],[7, 12],[8, 9],[8, 10],[8, 11],[8, 12]]
index combinations, size 3 : [[0, 1, 2]]
combinations, size 3: [[1, 5, 9],[1, 5, 10],[1, 5, 11],[1, 5, 12],[1, 6, 9],[1, 6, 10],[1, 6, 11],[1, 6, 12],[1, 7, 9],[1, 7, 10],[1, 7, 11],[1, 7, 12],[1, 8, 9],[1, 8, 10],[1, 8, 11],[1, 8, 12],[2, 5, 9],[2, 5, 10],[2, 5, 11],[2, 5, 12],[2, 6, 9],[2, 6, 10],[2, 6, 11],[2, 6, 12],[2, 7, 9],[2, 7, 10],[2, 7, 11],[2, 7, 12],[2, 8, 9],[2, 8, 10],[2, 8, 11],[2, 8, 12],[3, 5, 9],[3, 5, 10],[3, 5, 11],[3, 5, 12],[3, 6, 9],[3, 6, 10],[3, 6, 11],[3, 6, 12],[3, 7, 9],[3, 7, 10],[3, 7, 11],[3, 7, 12],[3, 8, 9],[3, 8, 10],[3, 8, 11],[3, 8, 12],[4, 5, 9],[4, 5, 10],[4, 5, 11],[4, 5, 12],[4, 6, 9],[4, 6, 10],[4, 6, 11],[4, 6, 12],[4, 7, 9],[4, 7, 10],[4, 7, 11],[4, 7, 12],[4, 8, 9],[4, 8, 10],[4, 8, 11],[4, 8, 12]]
You just have to iterate through all three arrays (matrixes) e.g. with nested loops.
How about this solution:
public class Easy {
public static void main(String[] argg) {
int[] m1 = new int[]{1,2,3,4};
int[] m2 = new int[]{5,6,7,8};
int[] m3 = new int[]{9,10,11,12};
printCombination(m1, m2, m3);
}
public static void printCombination(int[] first, int[] second, int[] third) {
for (int f : first) {
for (int s : second) {
for (int t : third) {
System.out.println("combination: " + f + ", " + s + ", " + t);
}
}
}
}
}
How to print a 2d array in java using a single for-loop?
I tried to search answers but only found solutions using multiple loops.
Example array:
[
[1, 2, 3],
[4, 5],
[6, 7, 8],
[9]
]
Example output (the exact format does not matter):
1, 2, 3, 4, 5, 6, 7, 8, 9
With a single for-loop, not a nested loop.
So not something like this:
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.print(array[i][j] + " ");
}
}
The principle to read a 2D array with a single loop : one [H,W] 2D matrix could be computed as a 1D matrix of HxW length.
On this basis a solution could be:
int[][] arr = {{1, 2, 3}, {4, 5, 8}, {5, 6, 7}};
int hight = arr.length;
int width = arr[0].length;
for (int i = 0; i < width * hight; i++) {
int li = i / hight;
int col = i % hight;
System.out.print(arr[li][col]);
if (col == width - 1) System.out.println();
}
Output:
123
458
567
If you need to know any algorithm for using only one loop you may try to use some like this:
public static void main(String[] args) {
int[][] arr = {{1, 2}, {3, 4}};
int currSubArrayNum = 0;
for (int i = 0; currSubArrayNum < arr.length; i++) {
System.out.println(arr[currSubArrayNum][i]);
if (i == arr[currSubArrayNum].length - 1) {
currSubArrayNum++;
i = -1;
}
}
}
Output will be next:
1
2
3
4
But if you need some simple solution for use in your program just use Arrays.toString:
public static void main(String[] args) {
int[][] arr = {{1, 2}, {3, 4}};
for (int[] anArr : arr) {
System.out.println(Arrays.toString(anArr));
}
}
With output:
[1, 2]
[3, 4]
You can define the for statement without an increment expression and transfer control of it to the inner if statement as follows:
int[][] arr = {{1, 2, 3}, {4, 5}, {6, 7, 8}, {9}};
for (int i = 0, j = 0; i < arr.length; ) {
if (arr[i] != null && j < arr[i].length) {
System.out.print(arr[i][j] + ", ");
j++;
} else {
j = 0;
i++;
}
}
Output:
1, 2, 3, 4, 5, 6, 7, 8, 9,
Create row and col pointer and update when they reach the edge.
Swift code:
func singleLoopArrayTraversal(_ data: [[Int]]) {
//Time complexity: O(n)
if data.count == 0 {
return
}
var row = 0
var col = 0
while row < data.count {
print("data[\(row)][\(col)] : \(data[row][col])")
if col == data[row].count - 1 {
row += 1
col = -1
}
col += 1
}
}
singleLoopArrayTraversal([[1, 2], [3, 4], [5, 6]])
Given a provided array, determine how many groups of a specified size exist.
For the array [1,1,1,2,2,2,3,3,3,4,5,6,7] , there are 7 groups with at least one, 3 groups with at
least 2, and 3 groups with at least 3. A group is a series of same values. 1 1 1 is a group of 3, but it also is
a group of 1 and 2. To count as a group, all values must be the same. 1 1 1 is a group of 3 because there
are 3 1s in a row.
Sample output:
[3, 3, 3, 3, 3, 9, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8]
size 1 count == 7
size 2 count == 6
size 3 count == 5
size 4 count == 3
size 5 count == 2
size 6 count == 1
My main code:
import static java.lang.System.*;
import java.util.Arrays;
import java.util.Scanner;
import static java.lang.System.*;
import java.util.Arrays;
import java.util.Scanner;
public class ArrayStats {
int[] numArray;
int number;
public ArrayStats(int[] a) {
setArray(a);
}
public void setArray(int[] a) {
numArray = a;
}
public int getNumGroupsOfSize() {
int cnt = 0;
for (int i = 0; i < numArray.length - 1; i++) {
if (numArray[i] == numArray[i + 1])
cnt++;
for (int j = 0; j <= 9; j++) {
if (cnt == i)
number = cnt;
else if (cnt == 1)
number = 1;
}
}
return number;
}
public String toString() {
return "size count" + " == " + getNumGroupsOfSize() + Arrays.toString(numArray);
}
}
My runner code:
public class ArrayStatsRunner
{
public static void main(String args[])
{
int[] one = {3, 3, 3, 3, 3, 9, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8};
ArrayStats test = new ArrayStats(one);
System.out.println(test.toString());
System.out.println("size 1 count == "+test.getNumGroupsOfSize(1));
System.out.println("size 2 count == "+test.getNumGroupsOfSize(2));
System.out.println("size 3 count == "+test.getNumGroupsOfSize(3));
System.out.println("size 4 count == "+test.getNumGroupsOfSize(4));
System.out.println("size 5 count == "+test.getNumGroupsOfSize(5));
System.out.println("size 6 count == "+test.getNumGroupsOfSize(6));
}
}
There is couple of problems with this method:
public int getNumGroupsOfSize() {
int cnt = 0;
for (int x = 0; x < numArray.length - 1; x++) {
if (numArray[x] == numArray[x + 1]);
cnt++;
for (int y = 2; y <= 9; y++) {
if (cnt == y)
number = cnt;
else if (cnt == 1)
number = 1;
}
}
return number;
}
Here is only some of the problems:
1. lets look at the second line:
for (int x = 0; x < numArray.length - 1; x++)
x < numArray.length - 1 will cause a problem because you wont check the last index of the array.
side note: it's a custom to use the letter i (index) and not x or y. If you are doing for loop inside for loop the custom is to do:
for (int i = 0; i < numArray.length - 1; i++)
{
for (int j = 0; j < numArray.length - 1; j++)
{
//some line of code
}}
This line of code if (numArray[x] == numArray[x + 1]);will do nothing because you put ; in the end of the row. Even if numArray[x] == numArray[x + 1]is true it wont do cnt++;.
Please check and learn from this code:
public class Main {
public static void main(String [] args)
{
int[] nums = {3, 3, 3, 3, 3, 9, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8};
System.out.println(+getGroupSize(nums,9)); //prints 1
System.out.println("size two== "+groupCount(nums,2)); //prints 6
System.out.println("size three== "+groupCount(nums,3));//prints 5
int[] nums2={1,1,1,2,2,2,3,3,3,4,5,6,7};
System.out.println(+getGroupSize(nums2,1)); //prints 3
System.out.println("size two== "+groupCount(nums2,2)); //prints 3
System.out.println("size two== "+groupCount(nums2,3)); //prints 3
System.out.println("size two== "+groupCount(nums2,5)); //prints 0
}
public static int getGroupSize(int[] array, int specificNumber ) {
/*This method prints the number of times a specific number exist in a array.
example: if the input of specificNumber is 3. in this array:
int[] nums = {3, 3, 3, 3, 3, 9, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8};
the method will return 5.
if the number is 9 is method will return 1. if number is 7 the method will return 3
*/
int groupCount = 0; //counts the number of times a specific number exist in a array
for (int i = 0; i <= array.length - 1; i++) { //this for loop will check every number in array
if (array[i] ==specificNumber) {
groupCount++;// if the current number of the array is the specificNumber, then the count will do plus one
}
}
return groupCount; //return the count
}
public static int groupCount(int[] array, int groupSize)
{
int groupCount=0;
int currentGroup=array[0]; //initialize the current group to be the first group of the array
if(getGroupSize(array, array[currentGroup])>=groupSize)
{ //check the size of the first group
groupCount++;
}
for (int i = 0; i <= array.length - 1; i++) {
if (array[i] !=currentGroup) { //checks if the current number is equal to the current group value
if(getGroupSize(array, array[i])>=groupSize)
{
groupCount++;
}
currentGroup=array[i]; // restart the currentGroup to be the current valume of the array
}
} //end of for loop
return groupCount;
}
private static void print(int [] array) {
for (int i = 1; i < 10; i++) {
System.out.println("size " +i+" group:" +groupCount(array, i));
}
}
}
//Below is my implementation how I improve that?
int[] numbers = { 1, 5, 23, 2, 1, 6, 3, 1, 8, 12, 3 };
int count = 0;
int length = numbers.length;
for(int i=0; i<length; i++){
for(int j= i+1;j<length; j++ ){
if(j!=i && numbers[i]==numbers[j]){
count+=1;
}
}
}
Solution in O(n):
public static void main(String[] args) {
int[] numbers = { 1, 5, 23, 2, 1, 6, 3, 1, 8, 12, 3 };
int count = 0;
Map<Integer, Integer> elements = new HashMap<>();
for (int i = 0; i < numbers.length; i++) {
Integer e = elements.get(numbers[i]);
if (e == null){
e = 0;
}
count += e;
elements.put(numbers[i], e+1);
}
System.out.println("count: "+count);
}
For [1, 1, 1, 1] you expect 6. In that case we are looking for all pairs {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}} which is the same as 6 * (6 - 1) / 2. Note that this is the same as combinations of 6 elements taken 2 at a time. Some python code follows:
def dupes(arr):
numdict = dict()
for idx in arr:
numdict[idx] = numdict.get(idx, 0) + 1
count = 0
for key, val in numdict.items():
if val > 1:
count = count+val*(val-1)//2 # The // 2 means divide by 2 and ignore decimal part
return count
>>> dupes([1, 1, 1, 1])
6
>>> dupes([1, 5, 23, 2, 1, 6, 3, 1, 8, 12, 3])
4
A dict in python is equivalent to a hashmap in Java.