Java: Convert int[] to smallest representation as ranges Java: Convert int[] to smallest representation as ranges arrays arrays

Java: Convert int[] to smallest representation as ranges


Try this:

private static void appendRange(StringBuilder sb, int begin, int end) {    sb.append(",").append(begin);    if (end != begin)        sb.append("-").append(end);}public static String sequenceNums(int[] nums) {    StringBuilder sb = new StringBuilder();    if (nums.length == 0) return sb.toString();    int begin = nums[0], end = nums[0];    for (int cur : nums)        if (cur - end <= 1)            end = cur;        else {            appendRange(sb, begin, end);            begin = end = cur;        }    appendRange(sb, begin, end);    return sb.substring(1);}@Testpublic void testSequenceNums() {    assertEquals("1-5,9,13-15", sequenceNums(new int[] {1, 2, 3, 4, 5, 9, 13, 14, 15}));    assertEquals("4,6,8,10-12,15,17", sequenceNums(new int[] {4, 6, 8, 10, 11, 12, 15, 17}));    assertEquals("1-7", sequenceNums(new int[] {1, 2, 3, 4, 5, 6, 7}));    assertEquals("", sequenceNums(new int[] {}));}


In the for loop you have two issues:

1) The second if should be if (previous == rangeStart) {

2) You're not dealing with the last number in the loop (where i == (nums.length - 1)).

I would do this with the following code:

public static String sequenceNums(int[] nums) {    StringBuilder sb = new StringBuilder();    int rangeStart = nums[0];    int previous = nums[0];    int current;    int expected = previous + 1;    int size = nums.length;    for (int i = 1 ; i < size ; i++) {        current = nums[i];        expected = previous + 1;        if (current != expected) {            addRange(sb, rangeStart, previous);            rangeStart = current;        }        previous = current;    }    addRange(sb, rangeStart, nums[size - 1]);    return sb.toString();}private void addRange(StringBuilder sb, int from, int to) {    if (sb.length() > 0) {        sb.append(",");    }    if (from == to) {        sb.append(from);    } else {        sb.append(from + "-" + to);    }}


Here is your fixed code.

public class TestSequencing {    public static void main(String[] args) {        int[] numbers1 = {1, 2, 3, 4, 5, 9, 13, 14, 15};        String numbers1s = "1-5,9,13-15";        System.out.println(Arrays.toString(numbers1));        System.out.println("Expected:\t" + numbers1s);        System.out.println("Produced:\t" + sequenceNums(numbers1) + "\n");        int[] numbers2 = {3, 5, 6, 9, 12};        String numbers2s = "3,5-6,9,12";        System.out.println(Arrays.toString(numbers2));        System.out.println("Expected:\t" + numbers2s);        System.out.println("Produced:\t" + sequenceNums(numbers2) + "\n");        int[] numbers3 = {1, 2, 3, 4, 5, 6, 7};        String numbers3s = "1-7";        System.out.println(Arrays.toString(numbers3));        System.out.println("Expected:\t" + numbers3s);        System.out.println("Produced:\t" + sequenceNums(numbers3) + "\n");    }    public static String sequenceNums(int[] nums) {        StringBuilder sb = new StringBuilder();        int rangeStart = nums[0];        int previous = nums[0];        int current;        int expected = previous + 1;        for (int i = 1 ; i < nums.length ; i++) {            current = nums[i];            expected = previous + 1;                           if (current != expected || i == (nums.length - 1)) {                if (current == rangeStart) {                    sb.append(previous + ",");                } else {                    if(rangeStart != previous) {                        if(i == nums.length - 1)                            sb.append(rangeStart + "-" + current);                        else                            sb.append(rangeStart + "-" + previous + ",");                    } else {                        if(i == nums.length - 1)                            sb.append(rangeStart + "," + current);                        else                            sb.append(rangeStart + ",");                    }                }                                rangeStart = current;            }                          previous = current;        }        if (sb.charAt(sb.length() - 1) == ',') {            sb.deleteCharAt(sb.length() - 1);        }        return sb.toString();    }}

Problem was, if current is not same as range starting value, you need to check for two cases

i) if range was starting with the same previous value. If so, no need to have same number separated by range (ex: 9-9 doesn't make sense. only 9 does). Another case to be handled is end of array reached. In case end of array is reached, it should just be added at the end even thought it does not fall in any range

ii) other wise, range starts and ends with previous value if end of array is not reached. If end of array is reached that would be end value of range