有没有更快的方法来比较Java中的两个Int数组?

时间:2014-06-02 09:28:32

标签: java arrays performance

我有两个整数数组,每个相同的大小说n (n是可变的,所以我可以有两个大小的数组,例如4或5或6等)和每个数字的值范围可以采用 0-9 的范围。 示例

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

现在,我想比较一号和一号阵列。两个这样的 1)我可以获得相同且位置相同的元素数量。 2)我可以得到相同但不在同一位置的数字计数。

我采取的方法是

For(1)迭代数组1,对于每个索引,我检查one[i] == two[i]。 - 简单。

For(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棋盘游戏的黑白钉计算的基本比较方法。 谢谢 沙克蒂

更新1: 1)Rudi的建议将Integer []改为int []

2)使用Dave Challis的解决方案 性能变化 对于7776 X 7776计算

OLD 46950 ms
NEW 42887 ms

4 个答案:

答案 0 :(得分:5)

虽然这可能不是您想要的,但我们可以通过非常简单的更改显着减少操作次数。

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

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

这将使处理过程少量,但不能通过优化排序/搜索逻辑本身。我们所做的就是删除自动装箱和自动拆箱操作。但是,如果你这么大规模地做这件事,那么这可能会产生很大的不同。

答案 1 :(得分: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]可以提高性能,因为它通常是错误的,因此不需要检查其他内容。

答案 2 :(得分:3)

下面的解决方案是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

答案 3 :(得分:0)

为什么不使用现有的实用程序方法来比较aaarays。他们肯定更快。您可以检查&#34; equals&#34;的实施情况。方法并确认。

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");
   }

}