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