簡體   English   中英

找出兩個排序列表是否包含相同元素Java的有效方法。

[英]Efficient way to find out if two sorted lists contain same element Java.

我有一個緊密的循環來搜索coprimes。 列表primeFactors 它的第n個元素包含n的素數分解的排序列表。 我正在檢查cd是否是使用checkIfPrimes

boolean checkIfPrimes(int c, int d, List<List<Integer>> primeFactors) {
    List<Integer>  common = new ArrayList<>(primeFactors.get(d)); //slow
    common.retainAll(primeFactors.get(c));        
    return (common.isEmpty());
}

primeFactors.get(d).retainAll(primeFactors.get(c))看起來很有希望,但它會改變我的可重用的primeFactors對象。

創建新對象相對較慢。 有沒有辦法加快這一步? 我可以以某種方式利用列表排序的事實嗎? 我應該使用數組嗎?

你可以使用一個Collection具有更快的查詢-如Set ,如果你只需要首要因素不重復,或Map ,如果你還需要各因素的計數。

基本上,您想知道兩個集合的交集是否為空。 Oracle Set教程顯示了一種計算相交的方法(類似於您已經提到的,在副本上使用retainAll ,但是在設置上操作應該更有效)。

由於您的列表相對較小,並且此操作經常執行,因此您應該避免創建任何新的列表或集合,因為它可能會導致GC壓力。

掃描線性算法是

public static boolean emptyIntersection(List<Integer> sortedA, List<Integer> sortedB) {
    if (sortedA.isEmpty() || sortedB.isEmpty())
        return true;
    int sizeA = sortedA.size(), sizeB = sortedB.size();
    int indexA = 0, indexB = 0;
    int elementA = sortedA.get(indexA), elementB = sortedB.get(indexB);
    while (true) {
        if (elementA == elementB) {
            return false;
        } else if (elementA < elementB) {
            indexA++;
            if (indexA == sizeA)
                return true;
            elementA = sortedA.get(indexA);
        } else {
            // elementB < elementA
            indexB++;
            if (indexB == sizeB)
                return true;
            elementB = sortedB.get(indexB);
        }
    }
}

還要考慮使用原始int的列表而不是盒裝整數,例如來自fastutil庫。

通常,您可以使用布爾數組。 其中數組的索引是數字,並且布爾值的值在為prim時返回true ,否則為false

你可以做一些事情:

List<Integer> commonElements = 
       primeFactors.get(d).stream()
                          .filter(primeFactors.get(c)::contains)
                          .collect(Collectors.toList());

一旦你測量了這個性能,就可以用'parallelStream()'代替上面的'stream()',看看你得到了什么好處。

設置操作應該比數組操作更快。 只是為了解決問題,請考慮嘗試並將性能與流性能進行比較:

final Set<Integer> commonSet;
final Set<Integer> cSet = new HashSet<Integer>();
final Set<Integer> dSet = new HashSet<Integer>();

cSet.addAll(primeFactors.get(c));
dSet.addAll(primeFactors.get(d));

commonSet = dSet.retainAll(cSet);

return (commonSet.isEmpty());

另外,考慮使用List<Set<Integer>> primeFactors而不是List<List<Integer>> primeFactors因為我懷疑你實際上沒有素數因子列表但實際上有一組素因子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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