我们常会遇到比如司机在线时长统计的这种类型计算,
如
求并集[1,2],[4,5],[5,9],结果是[1,2],[4,9]
求所有的交集为[]
但是求相交部分为[1,2],[5,5],
三个类型,对应下面三个小函数
type TimeInterval struct {
Start int
End int
}
type TimeSlice []TimeInterval
// 求全局的并集
func (ts TimeSlice) Union()TimeSlice{
if len(ts) <= 1{
return ts
}
sort.SliceStable(ts, func(i, j int) bool {
return ts[i].Start <= ts[j].Start
})
res := TimeSlice{ts[0]}
for key, val := range ts{
if key == 0{
continue
}
if val.Start >= res[len(res)-1].Start && val.Start < res[len(res)-1].End{
if val.End > res[len(res)-1].End{
res[len(res)-1].End = val.End
}
}else{
res = append(res, val)
}
}
return res
}
// 求全局的交集
func (ts TimeSlice)Intersect()TimeSlice{
if len(ts) <= 1{
return ts
}
sort.SliceStable(ts, func(i, j int) bool {
return ts[i].Start < ts[j].Start
})
res := TimeSlice{ts[0]}
for key, val := range ts{
if key == 0{
continue
}
if val.Start >= res[0].Start && val.Start <= res[0].End{
res[0].Start = val.Start
if val.Start < res[0].End{
res[0].End = val.End
}
}else {
return res[:0]
}
}
return res
}
// 求部分的交集
func (ts TimeSlice)IntersectSome()TimeSlice{
if len(ts) <= 1{
return ts
}
sort.SliceStable(ts, func(i, j int) bool {
return ts[i].Start < ts[j].Start
})
res := TimeSlice{ts[0]}
for key, val := range ts{
if key == 0{
continue
}
if val.Start >= res[len(res)-1].Start && val.Start <= res[len(res)-1].End{
res[len(res)-1].Start = val.Start
if val.Start < res[len(res)-1].End{
res[len(res)-1].End = val.End
}
}else {
res = append(res, val)
}
}
return res
}
func RunMergeInterval(){
case1:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{10,100},TimeInterval{11,200}}
case2:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{1,100},TimeInterval{1,200}}
case3:= TimeSlice{TimeInterval{1,2}, TimeInterval{2,5}, TimeInterval{1,9},TimeInterval{1,100},TimeInterval{1,200}}
// res = [[1 100] [101 102]]
re := case1.Union()
fmt.Println(re)
fmt.Println(case1.Intersect(), case2.Intersect(), case1.IntersectSome(), case3.IntersectSome())
//[{1 9} {10 200}]
//[] [{2 5}] [{2 2} {11 200}] [{2 5}]
}