簡體   English   中英

有沒有更快的方法來比較Java中的兩個Int數組?

[英]Is there a faster way to compare two Int arrays in Java?

我有兩個相同大小的整數數組, 比如n (n是可變的,所以我可以有兩個大小的數組,比如4或5或6等),每個數字可以取的值范圍是0-9

Integer[] one = {1,9,3,4} 
Integer[] two = {1,1,9,3}

現在,我想比較第一和第二陣列,以便1)我可以獲得相同且位置相同的元素數量。 2)我可以得到相同但不在同一位置的數字計數。

我采取的方法是

對於(1)迭代數組1並且對於每個索引,我檢查one[i] == two[i] - 簡單

對於(2)迭代兩個數組並且對於i != j查看元素是否相同,如果相同則將它們標記為-1以避免將來發生沖突。

for(int i =0;i<one.length;i++){
    for(int j=0;j<two.length;j++){
        if(i != j && one[i] != -1 && two[j] !=-1)){
            if(one[i] == two[j]){
                whiteCount++
                one[i] = -1;
                two[j] = -1;
            }
        }
    }
}

:現在我想知道是否有更快的方法來做同樣的事情? ESP。 計算問題的(2)部分 這是獲得Mastermind棋盤游戲的黑白釘計算的基本比較方法。 謝謝Shakti

更新1: 1)Rudi的建議將Integer []更改為int []

2)使用Dave Challis的解決方案7776 X 7776計算的性能變化

OLD 46950 ms
NEW 42887 ms

雖然這可能不是您想要的,但我們可以通過非常簡單的更改顯着減少操作次數。

Integer[] one = {1,9,3,4} 
Integer[] two = {1,1,9,3}

int[] one = {1,9,3,4} 
int[] two = {1,1,9,3}

這將使該過程加速少量,但不是通過優化排序/搜索邏輯本身。 我們所做的就是刪除自動裝箱和自動拆箱操作。 但是,如果你這么大規模地這樣做,那么這可以產生實質性的差異。

要獲得相同但在不同位置的數字的計數,您可以執行此操作。

public static long[] encode(int... nums) {
    long[] ret = new long[nums.length];
    for (int i = 0; i < nums.length; i++) {
        ret[i] = ((long) nums << 32) + i;
    }
    Arrays.sort(ret);
}

// encode both arrays and do a merge sort, skipping matches which have the same index.

這是O(n log N)操作。


您可以移動one[i] != -1簽出,以便它可以跳過該值。

int[] one = {1,9,3,4}; // Using int is faster and clearer.
int[] two = {1,1,9,3};

for (int i = 0; i < one.length; i++){
    if (one[i] == -1) continue;
    for (int j = 0; j < two.length; j++){
        if (one[i] == two[j] && i != j && two[j] != -1) {
            whiteCount++
            one[i] = -1;
            two[j] = -1;
        }
    }
}

首先放置one[i] == two[j]可以提高性能,因為它通常是假的,因此不需要檢查其他內容。

下面的解決方案是O(2N),不使用任何其他庫,也不修改初始數組。

它遍歷兩個數組一次,以獲得相同位置的整數計數。 雖然它這樣做,但它會在第二個數組中構建每個數字的counts (並存儲在數組數組中)。

然后它再次遍歷第一個數組,獲得在第二個數組中找到每個數字的總次數:

final Integer[] one = {1,9,3,4};
final Integer[] two = {1,1,9,3};

int samePositionCount = 0;
int sameNumberCount = 0;

// tracks number of times an int is in the 2nd array
final Integer[] counts = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

for (int i = 0; i < one.length; i++) {
    if (one[i].equals(two[i])) {
        samePositionCount++;
        counts[one[i]] = -1; // mark as seen in same position count
    } else if (counts[two[i]] != -1) {
        counts[two[i]]++;
    }
}

for (int i : one) {
    if (counts[i] > 0) {
        sameNumberCount += counts[i];
        counts[i] = 0; // avoid adding twice
    }
}

System.out.println(samePositionCount + " " + sameNumberCount);

打印:

1 2

為什么不使用現有的實用工具方法來比較aaarays。 他們肯定更快。 您可以檢查“equals”方法的實現並確認。

import java.util.Arrays;

class Test {
public static void main(String[] args) {
    int inarr1[] = {1, 2, 3};
    int inarr2[] = {1, 2, 3};
    Object[] arr1 = {inarr1};
    Object[] arr2 = {inarr2};
    if (Arrays.deepEquals(arr1, arr2))
        System.out.println("Same");
    else
        System.out.println("Not same");
   }

}

暫無
暫無

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

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