展开全部
和伪代码的上贴一致,只是由“新日期为准”,改成32313133353236313431303231363533e59b9ee7ad9431333335316562“新输入为准”,更符合原命题。
感觉这题涉及混流或矢量加减的技巧。这种技巧也是我该练习的。
Java 8代码,不够纯,但新特点基本用到了。import java.io.FileInputStream;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test {
static public class Record implements Cloneable{
public LocalDate start,end;
public int price;
@Override public Record clone(){
try{ return (Record) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();return null;
}
}
public String toString(){
return start.toString()+"~"+end.toString()+":"+price;
}
}
public static void main(String[] args) throws Exception{
FileChannel fc = new FileInputStream("data.txt").getChannel();
CharBuffer buf=Charset.forName("GBK").decode(fc.map(MapMode.READ_ONLY, 0,fc.size()));
Matcher m=Pattern.compile("(\\d+-\\d+-\\d+)~(\\d+-\\d+-\\d+)\\s+(\\d+)").matcher(buf);
List list=new LinkedList();
//Stream s=Stream.empty();
while(m.find()){
System.out.println(m.group());
Record rec=new Record();
rec.start=LocalDate.parse(m.group(1));
rec.end=LocalDate.parse(m.group(2));
rec.price=Integer.parseUnsignedInt(m.group(3));
if(list.size()==0) list.add(rec);
else{
Map> map=list.parallelStream().collect(Collectors.groupingBy(
(e)->{
int ss=rec.start.compareTo(e.start), se=rec.start.compareTo(e.end),
es=rec.end.compareTo(e.start), ee=rec.end.compareTo(e.end);
return new Integer(
(ss<=0 && es>=0 && ee<0 )?1://1 只往尾部缩小e的情况
(ss>0 && se<0 && ee<0)? 2: //2分割e为首、尾两份的情况
(ss>0 && se<0 && ee>=0)? 3: //3往首部缩小e的情况
0 //互不影响的情况
);
}
));
//System.out.println("map:"+map);
List type_tail=map.get(1),type_middle=map.get(2),
type_head=map.get(3), type_rest=map.get(0);
if(type_tail!=null && type_middle!=null && type_head!=null &&
type_tail.isEmpty() && type_middle.isEmpty() &&
type_head.isEmpty()) list.add(rec);
else{
list=type_tail==null?new LinkedList<>():
type_tail.parallelStream().map((e)->{
if(rec.price==e.price){
rec.end=e.end;//价格相等时,rec取代e
return null;
}
e.start=rec.end;
return e;}).filter(e->e!=null).collect(Collectors.toList());
if(type_middle!=null) list.addAll(type_middle.parallelStream().flatMap((Record e)->{
if(rec.price==e.price){
rec.start=e.start;
rec.end=e.end;//价格相等时,rec取代e
return null;
}
Record h=e.clone();
h.end=rec.start; e.start=rec.end;
return Stream.of(h,e);
}).filter(e->e!=null).collect(Collectors.toList()));
if(type_head!=null) list.addAll(
type_head.parallelStream().map((e)->{
if(rec.price==e.price){
rec.start=e.start;//价格相等时,rec取代e
return null;
}
e.end=rec.start; return e;
}).filter(e->e!=null).collect(Collectors.toList()));
if(type_rest!=null) list.addAll(type_rest);
list.add(rec);
}
//System.out.println("list:"+list);
}
}
System.out.println("按后输入数据覆盖:");
list.stream().sorted((a,b)->{
int s=a.start.compareTo(b.start);
return s==0?a.end.compareTo(b.end):s;
}).forEachOrdered((r)->System.out.println(r));
}
}2013-08-01~2013-08-31 300
2013-08-25~2013-09-30 300
2014-08-01~2014-12-31 300
2014-10-01~2014-10-07 500
按后输入数据覆盖:
2013-08-01~2013-09-30:300
2014-08-01~2014-10-01:300
2014-10-01~2014-10-07:500
2014-10-07~2014-12-31:300
具有合并和分割的功能