1

This is bending my brain and wondering if I could get a suggestion.

The grouping of sublists will depend on the size of the original group which will vary. But if I have this :

 [0,    1,  2,   3,     4,  5,  6,  7,  8,  9,  10,     11]

I need those grouped into this

 [0,     4,       8]
 [1,     5,       9]
 [2,     6,       10]
 [3,     7,       11]

and if I have this:

 [0,    1,  2,   3,     4,  5,  6,  7]

I will need it split into 4 like this:

 [0,     4]
 [1,     5]
 [2,     6]
 [3,     7]

I will need to find the smallest of each smaller group but I can handle that.

Edited: Sorry forgot to mention that this shows 4 arrays each time but it could be 3 or 5 or another value. I think that makes this even more complex.

3
  • Sorry but could you clarify "find the smallest of each smaller group"? Initially I though that you ware asking how to know how many elements will each of those 4 "groups" contain, but now I am not sure what you are trying to ask. Commented Feb 5, 2021 at 20:48
  • try using modulus in your algo bro Commented Feb 5, 2021 at 21:02
  • What logic do you use to split your initial array up into groups? Commented Feb 6, 2021 at 0:21

4 Answers 4

4

Variables

There are two variables in the grouping algorithm

  1. size of input array
  2. number of groups (or number of elements per group)

Behavior

  1. group the input array based on the input parameter
  2. if the size of array is not an exact multiple of number of groups, some groups might have different count than others

algorithm (assuming number of groups(N) are given)

  1. Initialize a list of lists (outer list will contain N lists)
  2. Iterate over the input array
  3. Let the current index of input array be i
  4. Add the element to i % Nth list as list.get(i % N).add(input[i])

code

  public List<List<Integer>> group(int[] input, final int groupCount) {
    List<List<Integer>> groups = IntStream.range(0, groupCount)
      .mapToObj(i -> new ArrayList<Integer>())
      .collect(Collectors.toList());
    for (int i = 0; i < input.length; i++) {
      groups.get(i % groupCount).add(input[i]);
    }
  }
Sign up to request clarification or add additional context in comments.

Comments

1

So basically: You want to split an array into four arrays every time?

Then you could just do the following:

public static List<Integer[]> getSubArrays(int[] target, int numberOfArrays)
{
    System.out.println("+++");
    List<Integer[]> arrays = new ArrayList<>();     
    for(int i = 0; i<numberOfArrays; i++)
    {
        
        Integer[] partArray = new Integer[target.length/numberOfArrays];
                
        int itt = 0;
        for(int b = i; b<target.length; b=b+numberOfArrays)
        {
            partArray[itt++] = target[b];
        }
        
        System.out.println(Arrays.deepToString(partArray));
        arrays.add(partArray);
        
    }
    return arrays;
    
    
}

public static void main(String[] args)
{
    
    int[] firstArray =  {0,1,2,3,4,5,6,7,8,9,10,11};
    int[] secondArray = {0,1,2,3,4,5,6,7};
    int[] thirdArray = {0,1,2,3};
    int[] unequalArray = {0,1,2,3,4};
    
    getSubArrays(firstArray,4);
    getSubArrays(secondArray,4);
    getSubArrays(thirdArray,4);
    getSubArrays(unequalArray,4);
}

Outputs:

+++
[0, 4, 8]
[1, 5, 9]
[2, 6, 10]
[3, 7, 11]
+++
[0, 4]
[1, 5]
[2, 6]
[3, 7]
+++
[0]
[1]
[2]
[3]
+++
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
        at Test.getSubArrays(Test.java:18)
        at Test.main(Test.java:41)

3 Comments

Intentional. You can't split an array with five elements into four arrays of the same size ;)
It won't be 4 every time but I can determine if its 4 or another value. So is this being dynamic not going to work because you are statically setting up 4 sub arrays?
It works as long as target.length/numberOfArrays is a smooth integer.
1

Here are three solutions, the first is for a list of lists. The second is for an array of arrays. Each method throws an exception if the supplied array length is not an integral multiple of the group size.

The third method permits non integral multiples of the group size.

All the methods utilize nested streams to create the desired result.

int[] v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };

List<?> lists = groupLists(v, 4);
for (Object o : lists) {
    System.out.println(o);
}
int[][] vals = groupArrays(v, 4);
for (int[] o : vals) {
    System.out.println(Arrays.toString(o));
}

Both of the above print

[0, 4, 8]
[1, 5, 9]
[2, 6, 10]
[3, 7, 11]

Method to return lists

public static List<List<Integer>> groupLists(final int[] vals,
        final int groupSize) {
    if (vals.length % groupSize != 0) {
        throw new IllegalArgumentException(
                "Array length not a multiple of group size");
    }

    return IntStream.range(0, groupSize)
            .mapToObj(i -> IntStream
                    .range(0, vals.length / groupSize)
                    .mapToObj(k -> Integer
                            .valueOf(vals[k * groupSize + i]))
                    .collect(Collectors.toList()))
            .collect(Collectors.toList());
}

Method to return arrays

public static int[][]
        groupArrays(final int[] vals, final int groupSize) {
    if (vals.length % groupSize != 0) {
        throw new IllegalArgumentException(
                "Array length not a multiple of group size");
    }

    return IntStream.range(0, groupSize).mapToObj(
            i -> IntStream.range(0, vals.length / groupSize).map(
                    k -> Integer.valueOf(vals[k * groupSize + i]))
                    .toArray())
            .toArray(int[][]::new);
}

This method fills out the returned lists a much as possible by using a filter to avoid generating an index out of bounds exception.

int[] v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
List<?> lists = groupListsPartial(v, 4);
for (Object o : lists) {
    System.out.println(o);
}

prints

[0, 4, 8]
[1, 5, 9]
[2, 6]
[3, 7]

The method

public static List<List<Integer>> groupListsPartial(final int[] vals,
        final int groupSize) {
    
    return IntStream.range(0, groupSize)
            .mapToObj(i -> IntStream
                    .range(0, (vals.length+(groupSize-1)) / groupSize)
                    .filter(k->k*groupSize + i <vals.length)
                    .mapToObj(k -> Integer
                            .valueOf(vals[k * groupSize + i]))
                    .collect(Collectors.toList()))
            .collect(Collectors.toList());
}

Comments

0

I believe I got a way to do this based on whether the number of groups is 4 or other.

  i++ // in an outer loop

 .....................
 ArrayList compareSet = new ArrayList();
 int nCrement = 0;
 int nX = 4; // is 4 right now but could be something else
 for (int j = 0; j < listSet.size(); j++) {  
 String value = (String) listSet.get(i + nCrement);   // i is increased above
       compareSet.add(value);
       nCrement = nCrement + nX;
       j = nCrement;
 }
  
 ..........

// compareSet checks each group to see which is smallest then continues outer loop to get another group

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.