'Getting elements from an array where next element greater than previous by 1

I have an array:

int[] arr = {-4, -2, -1, 0, 1, 3, 4, 5, 6, 9, 10, 12, 13, 14, 18};

The array is ordered in ascending order. The main idea is to get elements and group them, where next element is greater than a previous by 1. The minimum length of such elements should be equal 3.

In output, I have to get a string:

"-4, (-2-1), (3-6), 9, 10, (12-14), 18"

The first interval is: -2, -1, 0, 1 - it should looks like range i.e -2-1

The next interval is: 3, 4, 5, 6 - it should looks like range i.e 3-6

9, 10 - the length is less than 3

So the last interval is:

12, 13, 14 it should looks like range i.e 12-14



Solution 1:[1]

this answer was pre-edit.

You are printing input[i] but you are expecting the values in input[i] - 1

when you run this in the debugger you can see it finds -1 (which has -2 before it, and equals -2 + 1). You then print the -1 you found.

If you want the output to contain the -2 , you should print input[i - 1]

post-edit:

you have grouped elements by braces which means you are looking for a sequence. This will require you to keep the start number somewhere. the code you originally posted (simple loop that checks left) will need a bit more work.

In rough terms:

if (continuing a range) 
    if(this number is still in range / +1) continue
    else: stop the range and print it (start point plus current -1). if current -1 is the start point, don't use braces and range indicator. if it is different use braces and - between start and end)
else 
    start a range. (keep track of the number you are on and continue.

that's what you need in pseudocode

Solution 2:[2]

Algorithm

You could loop through the array.

  1. If found consecutive number, add it to a group (e.g. List).
  2. If group satisfies minimum length (e.g. 3) then add it to output formatted as range (and clear the group).
  3. If no consecutive number, just add it to output.

Code

public static String formatAsRange(List<Integer> list) {
    return String.format("(%d-%d)", list.get(0), list.get(list.size()-1));
}

public static String consecutiveElements(int[] array, int minGroupLength) {
    StringBuilder sb = new StringBuilder();
    List<Integer> group = new ArrayList<>();
    for(int i = 0; i < array.length; i++) {
        if (i == 0 || array[i] == array[i-1] + 1) {
            group.add(array[i]);
        } else  {
            if (group.size() >= minGroupLength) {
                sb.append(formatAsRange(group)).append(',');                
            } else {
                var csv = group.stream().map(String::valueOf).collect(Collectors.joining(","));
                sb.append(csv).append(',');
            }
            group.clear();
            sb.append(array[i]).append(',');
        }
    }
    return sb.toString();
}

For your input it prints: -4,-2,(-1-1),3,(4-6),9,10,12,13,14,18,

See the demo on IDEone.

To do

So there is still something to fix. For example

  • expected range 12-14 is missing
  • expected range -2-1 is not complete with -2, (-1-1)
  • expected range 3-6 is not complete with 3, (4-6)
  • the last comma can be removed
  • can add a space following each comma

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Joeblade
Solution 2 hc_dev