Java:将int []转换为范围的最小表示形式

给定一个int值的数组,如何将这个序列解析为计数序列符号?

例子:

{1, 2, 3, 4, 5, 9, 13, 14, 15} -> "1-5,9,13-15"
{4, 6, 8, 10, 11, 12, 15, 17}  -> "4,6,8,10-12,15,17"

我正在寻找一种能产生这些结果的方法。 这是我迄今为止所做的,但是我非常难以忍受这一点:

测试代码:

import java.util.Arrays;
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 {
                    sb.append(rangeStart + "-" + previous + ",");
                }                
                rangeStart = current;
            }              
            previous = current;
        }
        if (sb.charAt(sb.length() - 1) == ',') {
            sb.deleteCharAt(sb.length() - 1);
        }
        return sb.toString();
    }
}

输出:

[1, 2, 3, 4, 5, 9, 13, 14, 15]
Expected:   1-5,9,13-15
Produced:   1-5,9-9,13-14

[3, 5, 6, 9, 12]
Expected:   3,5-6,9,12
Produced:   3-3,5-6,9-9

[1, 2, 3, 4, 5, 6, 7]
Expected:   1-7
Produced:   1-6

尝试这个:

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);
}

@Test
public 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[] {}));
}

在for循环中你有两个问题:

1)第二个if应该是if (previous == rangeStart) {

2)你没有处理循环中的最后一个数字(其中i == (nums.length - 1) )。

我会用下面的代码来做到这一点:

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);
    }
}

这是你的固定代码。

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();
    }

}

问题是,如果电流与量程起始值不一致,则需要检查两种情况

i)范围是否以相同的先前值开始。 如果是这样,不需要有相同的数字分隔范围(例如:9-9没有意义,只有9)。 另一个要处理的案例是到达数组的末尾。 如果达到数组的末尾,则应该在最后添加,即使它不在任何范围内

ii)其他方面,如果未达到阵列末端,则范围以先前的值开始和结束。 如果达到了数组的结尾,那将是范围的结束值

链接地址: http://www.djcxy.com/p/86427.html

上一篇: Java: Convert int[] to smallest representation as ranges

下一篇: Get screenshot of startmenu