[英]find if a number set has intersection with another set
背景:
防火牆訪問列表中的服務端口號有不同的格式,如:
單號:22443
范圍:10000-65535
我正在對防火牆進行一些分析,需要查找指定端口是否位於訪問列表端口號中
例如:
acl 服務端口是 String[] servicePorts = {"20-22","443","8080-8088","10000-65535"}
需要在 servicePorts 中查找 if {"5672","15672-15674"}
方案一:
將 servicePort 轉換成一個 Set,將 rest 作品留給 Set Api
方案二:
將端口轉換為統一格式,每個元素都有一個“開始結束”數字,如:
targetPorts = {“20-22”,“443-443”,“8080-8088”,“10000-65535”}
myPorts = {"5672-5672","15672-15674"}
然后需要循環 myPorts,根據 targetPorts 元素檢查每個元素並比較開始/結束編號。
Plan1 更簡單,但確實很重,因為端口集包含大量元素。
我考慮過可能有一些二進制操作方法,但沒有出路。
還有其他計划來處理數字交集問題嗎?
或者你更喜歡哪個計划。
讓我們快速分析一下到目前為止提到的 3 種方法。
我們使用以下變量進行分析:
n
a
(其中a >= n
)m
s
(其中s >= m
)方法 1:構建一組單獨的端口
O(a + s)
HashSet
,插入和查找的復雜度為 O(1),因此復雜度為O(a + s)
注意:如果您構建 acl 集,一旦復雜性降低到每個服務O(s)
。
方法 2:構建 acl 范圍的排序列表/樹並檢查服務范圍的未排序列表
O(n + m)
O((m + n) * log(n))
O(n * log(n))
O(m)
O(m * log(n))
(對於異常情況可能更多,但不太可能) 注意:如果您構建一次 acl 列表並且可以重復使用它,則每個服務的時間復雜度將降至O(m * log(n))
。
方法 3:構建單個標記列表並計算開始/結束(גלעד ברקן 建議的方法)
O(n + m)
O((n + m) * log(n + m))
O(n + m)
O((n + m) * log(n + m))
O(n + m)
注意:您可以為 acl 構建一次排序列表,為每個服務復制它並使用插入排序等來添加服務范圍。 這會將時間復雜度降低到O(m * log(n + m))
( O(m)
用於迭代m
個范圍, O(log(n + m))
用於查找每個范圍的插入點) .
結論
由於與O((n + m)*log(n + m))
) 和類似的 memory 相比,由於時間復雜度較低( O(n + m) * log(n))
,因此這種分析方法 2 更可取開發復雜性(盡管后者更主觀)。
對於非常小的范圍,方法 1 可能更可行,但可以轉得非常快,方法 2 具有更好的一般屬性(即對於未知數量和未知大小的范圍)。
計划 3,將每個開始和結束作為帶標簽的元組插入單個排序列表中
(t, start, 20), (t, end, 22), (t, start, 443), (t, end, 443), (m, start, 5672), (m, end, 5672), (t, start, 8080), (t, end, 8088), (t, start, 10000), (m, start, 15672)...
從小到大,對每一個label進行一次計數,遇到label的開始時加1,遇到label的結束時減1。其他也成為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.