Go 時間交並集小工具

2021-09-24 06:49:55 字數 2801 閱讀 7819

示例**(含測試)在這裡

在甘特圖的場景下,我們經常會遇到這種情況,五位員工a, b, c, d, e,可能他們的工作都是並行的,我們需要計算 某段時間內他們總的工作時長。

我們不能簡單得把五個人的工作時間都加起來,因為當中會有重疊的部分。 所以這時候我們就需要乙個計算時間交並集的工具。

將一組離散的時間段按照開始時間,從小到大排序。像這樣

[         ]

複製**

我這裡將時間用十分小的秒來代替,方便理解。

迴圈排序後的陣列,如果下乙個時間段開始時間介於上個時間段的開始時間和結束時間之間,那麼就進行合併,否則就分離。 可以看到我們這裡有兩個關鍵動作,合併分離,而這個就是我們要實現的核心**。

一段連續的工作時間都會有兩個點,開始時間結束時間。 所以我們可以把這個時間結構設計成:

type t struct 

複製**

而乙個人的工作時間是由多個 t 組成的,所以我們在定義乙個切片型別

type tslice t

複製**

為了能順序合併時間,我們需要將tslice進行排序。 我們知道 go 中有個 sort 包,我們只需要實現 sort 型別的介面,就能實現 tslice 的排序了。 我們實現下:

func

(t tslice)

len()

int

func

(t tslice)

swap

(i, j int)

func

(t tslice)

less

(i, j int)

bool

複製**

三個方法分別是,長度、交換位置、比小。

這樣一來,我們就能直接用sort.stable()穩定排序,對我們的時間段切片排序了。

好,接下來我們實現並集的方法,我們取名為union

func

(t tslice)

union

()tslice

return s

}複製**

union 方法將會返回乙個同樣的tslice時間切片,只不過是經過並集處理的。

一旦 t 中的時間段個數大於1,我們就要執行處理邏輯了:

if

len(t) > 1

複製**

我們先對時間切片進行排序,然後把第乙個時間段作為第乙個元素放進我們的結果 tslice 中,好讓我們開始進行循壞的比較。

if

len(t) > 1

// 第一組元素我們不做任何操作

if k == 0

// 當開始時間介於上乙個時間段的開始時間和結束時間之間

if v.start >= s[len(s)-1].start && v.start <= s[len(s)-1].end

// 如果大於上乙個時間段的結束時間

} else

if v.start > s[len(s)-1].end }}

}複製**

來張圖其實就清楚了:

可以看到最後輸出的也是乙個tslice型別。 上面就是 union,求並集的過程,那交集的?

其實交集也很簡單,如果兩個時間段相交,我們只要判斷:開始時間取最大的那個,結束時間取兩個時間段中最小的那個。

func

(t tslice)

intersect

()tslice

if k == 0

// 兩個時間段相交

if v.start >= s[0].start && v.start <= s[0].end

} else }}

return s

}複製**

一樣,我們來個圖:

需要注意的是,這個求交集的結果是全相交--只有當所有時間段都有共同時間才會有結果。 這樣的需求在實際過程中用到的是不是不太多??所以我想是不是能夠實現:一次相交,兩次相交...的條件篩選。

我們隨機生成了一組時間切片

func

maketimes

(t int)

tslice

return set

}testset := maketimes(10) // 生成10個時間段的時間切片

res := testset.union() // 直接呼叫 union() 或者 intersect()

複製**

輸入資料為:

[         ]

複製**

輸出結果:

複製**

結果還行~

我發現在求並集的過程中,會要求求最終的時間之和,所以我們為 tslice 加乙個 sum() 方法, 就是簡單的迴圈求和:

func

(t tslice)

sum()

(sum int64)

return sum

}複製**

呼叫方法:tslice.union().sum()

寫個 Go 時間交並集小工具

示例 含測試 在這裡在甘特圖的場景下,我們經常會遇到這種情況,五位員工a,b,c,d,e,可能他們的工作都是並行的,我們需要計算 某段時間內他們總的工作時長。我們不能簡單得把五個人的工作時間都加起來,因為當中會有重疊的部分。所以這時候我們就需要乙個計算時間交並集的工具。將一組離散的時間段按照開始時間...

時間取並交集的小工具(Go)

如求並集 1,2 4,5 5,9 結果是 1,2 4,9 求所有的交集為 但是求相交部分為 1,2 5,5 三個型別,對應下面三個小函式 type timeinterval struct type timeslice timeinterval 求全域性的並集 func ts timeslice un...

小工具 tree工具

wangyetao linux u1604 tree l 1 bin boot cdrom dev etc home initrd.img boot initrd.img 4.4.0 116 generic initrd.img.old boot initrd.img 4.4.0 112 gener...