我有两个整数数组,每个相同的大小说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
答案 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");
}
}