簡體   English   中英

查找數字集是否與另一組有交集

[英]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 種方法。

我們使用以下變量進行分析:

  • acl 范圍數: n
  • acl 中的端口數: a (其中a >= n
  • 服務范圍數量: m
  • 服務中的端口數: s (其中s >= m

方法 1:構建一組單獨的端口

  • 開發復雜性:簡單 - 添加單個值,遍歷范圍並將值放入集合或檢查它們
  • memory 復雜度:取決於端口數量(最多 65k 個條目)- O(a + s)
  • 時間復雜度:假設您使用的是大小合適的HashSet ,插入和查找的復雜度為 O(1),因此復雜度為O(a + s)

注意:如果您構建 acl 集,一旦復雜性降低到每個服務O(s)

方法 2:構建 acl 范圍的排序列表/樹並檢查服務范圍的未排序列表

  • 開發復雜度:簡單/中等——將單個值轉換為范圍,尋找潛在的重疊,檢查實際重疊
  • memory 復雜性:取決於范圍的數量,但可能遠低於端口數量 - O(n + m)
  • 時間復雜度: O((m + n) * log(n))
    • 構建 acl 列表: O(n * log(n))
    • 遍歷服務端口列表: O(m)
    • 查找並檢查每個服務端口范圍內的重疊: O(m * log(n)) (對於異常情況可能更多,但不太可能)

注意:如果您構建一次 acl 列表並且可以重復使用它,則每個服務的時間復雜度將降至O(m * log(n))

方法 3:構建單個標記列表並計算開始/結束(גלעד ברקן 建議的方法)

  • 開發復雜度:簡單/中等 - 構建標簽列表,跟蹤兩個標簽的計數
  • memory 復雜性:取決於范圍的數量,但可能遠低於端口數量 - O(n + m)
  • 時間復雜度: O((n + m) * log(n + m))
    • 迭代兩個列表的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM