• 时间取并交集的小工具(Go)


    我们常会遇到比如司机在线时长统计的这种类型计算,

    求并集[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}]
    }    
    

      

  • 相关阅读:
    Java的并发编程:创建线程的多种方式
    va_end (Variadic functions) – C 中文开发手册
    PHP headers_sent() 函数
    Java面试题:你用过的网站前端优化的技术有哪些?
    space-before-keywords (Rules) – Eslint 中文开发手册
    JavaScript 数据类型
    C 库函数 – free()
    屏幕 | screen (screen) – Electron 中文开发手册
    lrint (Numerics) – C 中文开发手册
    《《数据化风控》读书笔记分享》
  • 原文地址:https://www.cnblogs.com/lvpengbo/p/14564256.html
Copyright © 2020-2023  润新知