我有一个排序集,其元素为[1,2,3,4,5,10,12,45,46,47,50]
我需要将此集转换为Range语句,其中连续元素以min .. max表示。 这里确切的是预期的产出。
1..5 / 10/12 / 45..47 / 50
由于1至5是连续的,因此它们由1..5表示,因此表示为45..47
10,12等等是不连续的,因此它们被Union分开。任何人都可以帮我解决任何内置方法或高效算法吗? 目前我使用的是迭代器,但是卡在中间。
String SetToRange(Set<Integer> S, long maxint)
{
Integer min,max;
StringBuilder Range=new StringBuilder("");
Iterator I=S.iterator();
switch(S.size())
{
case 0: Range.append("0.."+maxint);
System.out.println("RangeStatement for Set Size 0 is"+Range);
return Range.toString();
case 1: min=max=(Integer)I.next();
Range.append(min);
System.out.println("RangeStatement="+Range);
return Range.toString();
case 2: min=(Integer)I.next();
max=(Integer)I.next();
if(max==min+1)
{
Range.append(min.toString()+".."+max.toString());
}
else
{
Range.append(min+"\\/"+max);
}
System.out.println("Range Statement:-"+Range);
return Range.toString();
}
System.out.println("The Set has more than Two Elements="+S.size());
min=(Integer)I.next();
max=(Integer)I.next();
//Working out logic for this Part using Two Iterators
return Range.toString();
}
谢谢,
答案 0 :(得分:2)
您可以在O(n)
时间执行此操作。此示例使用面向对象方法显示它。
首先创建一个Range
类。
class Range {
int from;
int to;
public Range setFrom(int from) {
this.from = from;
return this;
}
public Range setTo(int to) {
this.to = to;
return this;
}
@Override
public String toString() {
return "Range [from=" + from + ", to=" + to + "]";
}
}
现在只需迭代数组并比较相邻的元素。
如果它们的差异优于1,则它们不是连续的,因此您设置上一个范围的上限,将其添加到列表中,然后创建一个设置其下限的新值。
public class Test {
public static void main(String[] args){
Set<Integer> setOfIntegers = new LinkedHashSet<>(Arrays.asList(1,2,3,4,5,10,12,45,46,47,49));
System.out.println(getRanges(setOfIntegers));
}
public static List<Range> getRanges(Set<Integer> s){
List<Range> list = new ArrayList<>();
Integer[] setOfIntegers = s.toArray(new Integer[s.size()]);
Range r = new Range().setFrom(setOfIntegers[0]);
for(int i = 1; i < setOfIntegers.length; i++){
if(setOfIntegers[i] - setOfIntegers[i-1] != 1){
list.add(r.setTo(setOfIntegers[i-1]));
r = new Range().setFrom(setOfIntegers[i]);
}
}
list.add(r.setTo(setOfIntegers[setOfIntegers.length-1]));
return list;
}
}
一些输出:
[1,2,3,4,5,10,12,45,46,47,49] => [Range [from=1, to=5], Range [from=10, to=10], Range [from=12, to=12], Range [from=45, to=47], Range [from=49, to=49]]
[4,7,8,9,15,20,21] => [Range [from=4, to=4], Range [from=7, to=9], Range [from=15, to=15], Range [from=20, to=21]]
[-17,-6,-4,-3,-2,0,1,4] => [Range [from=-17, to=-17], Range [from=-6, to=-6], Range [from=-4, to=-2], Range [from=0, to=1], Range [from=4, to=4]]
请注意,我没有检查该集合是否没有元素等。但是您有一般性的想法,根据您的需要修改它应该不难。
答案 1 :(得分:0)
所以,你的基本功能是:
f(List<int>) => List<List<int>>
这样输出的内部列表保证只有连续的数字,并且没有两个这样的列表具有连续的数字。所以你的算法看起来像:
sort(List<int> input)
List<List<int>> output = new List<List<Int>>();
while (input.hasElements())
output.append( getNextConsecutive(input))//NOTE: getNextConsecutive modifies input!
return output
getNextConsecutive(List<int> input)
List<int> output = new List<int>();
while (input.next() == ouput.last() + 1) {
output.append(input.pop);//note: removes from input
}
return output
请注意,此算法省略了输出,因为它是一个单独的问题,应该由另一个函数自然处理:
printLists(List<List<int>> input)
for each List in input, sublist
if sublist.length > 1
print sublist.first
print ".."
print sublist.last
if sublist.length == 1
print sublist.first
print "/"
答案 2 :(得分:0)
以下是您问题的解决方案。
import java.util.Set;
import java.util.TreeSet;
public class SetRange {
public static String getRangeString(Set<Integer> rangeSet) {
StringBuffer strBuilder = new StringBuffer();
Integer lastValue = null;
boolean contineous = false;
for (Integer value : rangeSet) {
if (lastValue != null && lastValue + 1 == value.intValue()) {
contineous = true;
} else {
if (contineous) {
strBuilder.deleteCharAt(strBuilder.length() - 1);
strBuilder.append(".." + lastValue + "/" + value + "/");
} else {
strBuilder.append(value + "/");
}
contineous = false;
}
lastValue = value;
}
String answer = strBuilder.toString();
if (answer.length() > 0) {
answer = answer.substring(0, answer.length() - 1);
}
return answer;
}
public static void main(String[] args) {
Set<Integer> rangeSet = new TreeSet<Integer>();
rangeSet.add(1);
rangeSet.add(2);
rangeSet.add(3);
rangeSet.add(4);
rangeSet.add(5);
rangeSet.add(10);
rangeSet.add(12);
rangeSet.add(45);
rangeSet.add(46);
rangeSet.add(47);
rangeSet.add(50);
String answer = getRangeString(rangeSet);
System.out.println(answer);
}
}