如何对两个整数数组进行顺序不敏感比较

我想要以这种方式比较的Java代码(例如):

 =   !=  

我不能使用hashmap表或任何东西; 只是没有库的纯代码。

我知道有两种方法。

  1. 对它们进行排序并按索引比较数组索引
  2. 使用两个for循环并将外部索引与内部索引进行比较。 我一直在尝试这个但仍然没有工作:

     for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(a[i] != a[j] && j == n) return false; } } return true; 

代码有什么问题吗? 谢谢

排序和比较。 你不能比这更好地获得复杂性,你对速度所做的任何“改进”都会冒你的代码出错的风险。

[编辑]实际上….如果你知道你的数字相对较小(例如:数组只包含0到1000之间的数字),那么在O(n)中有另一种选择。 这样的事情(抱歉,如果语法错误,我最近没有使用java):

 int count[1001]; // already intialized to 0 for(int i=0;i 

免责声明:此代码不包含“健全性检查”(即数组实际上长度为“n”,数字在规定的时间间隔内) - 它只是为了说明原理。

 Arrays.sort(a); Arrays.sort(b); return Arrays.equals(a, b); 

由于这是家庭作业,我猜想一个简单的二次解决方案(你原来的尝试是),很好。 在这种情况下,你可以这样做:

 int count(int[] nums, int x) { int count = 0; for (int num : nums) { if (num == x) count++; } return count; } boolean equals(int[] arr1, int[] arr2) { if (arr1.length != arr2.length) return false; for (int x : arr1) { if (count(arr1, x) != count(arr2, x)) return false; } return true; } 

为了清晰起见,这就牺牲了速度:这显然是正确的!!

提示

  • 适用时,每次使用; 它总是读取更好的可读性
  • 帮助程序function提高了可读性和可重用性!

我认为在进行任何迭代之前检查两个数组的长度是否相等是明智的。 这是一种选择退出早期努力工作的廉价方式,它为您提到的第二种方法修复了以下类型的故障:

{1, 2, 3}被视为等于{4, 3, 2, 1}

这是一个O(n ^ 2)问题。 没有其他解决方案比直接比较两个arrays更快。

Virgil的解决方案很酷,除了它不是真正的O(n)性能。 它实际上是O(n + 1000)性能。 第二次设置布尔变量的数组比较是昂贵的,并且在小数组中适得其反。

你写的解决方案除了bug之外是最好的。

这是错误更正版本。

 boolean[] matchedPositions = new boolean[n]; for(int k = 0; k < n; k++ { matchedPositions[k] = false; } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(matchedPositions[j] == false && a[i] == a[j]) { matchedPositions[j] = true; break; } if(j == n - 1) { return false; } } } return true; 

在这种情况下,如果整数匹配,则内部循环将中断并设置或标记匹配的位置。 这对于具有重复条目的数组是必需的,这将避免左数组中的两个条目与右数组中的一个条目匹配。

如果匹配未发生,由j == n - 1标识,则返回false。

由于我们期望布尔值中的默认值为false,因此最好标记初始化它。

实际上,该解决方案具有O(n log n + n)性能损失。 排序和比较也具有O(n ^ 2 + n)的性能损失。 Sort具有O(n ^ 2)性能和一个用于检查的循环。 但排序会更改数组的内容,但事实并非如此。

如果你把一个数组作为1,2,3,4,3,1,2,4那么解决方案是这样的。

2n =整数总数:8

 //program int i, j, n = 4; for(i = 0; i < n; i++) for(j = n; j < 2n; j++) { if( a[i] != a[j]) { j++; } else { i++; exit(); } } if (i == n) { //They both are equal; } else if(i != n) { //They both are not equal; } 

如果它不起作用请评论它。 谢谢。

这是您发布的代码的修复程序。

 for(int i = 0; i < n; i++) { int j; for(j = 0; j < n; j++) { if(a[i] == b[j]) break; } if (j == n) return false; } return true; 

但是,对于包含重复项的数组,该算法将完成。 例如,将找到数组{1, 1, 2, 3}作为与数组{1, 2, 2, 3} 1,2,2,3 {1, 1, 2, 3}的匹配。

我强烈建议您实施排序和比较算法。

在实际启动计算复杂度更高的解决方案之前,可以运行快速O(n)测试以查看arrays是否相同。 有时这会导致误报,并且您可以使用更多计算密集型手段进一步调查。 如果返回false,则可以确保数组不同。

基本方法是在两个数组的第i个元素之间进行累积异或。 如果得到的XOR不为零,那么您就知道两个数组是不同的。 如果XOR为零,它们可能是相同的,但需要更多工作来确认。

 int c_xor = 0; // XOR accumulator for (int i = 0; i < n; ++i) c_xor ^= arr1[i] ^ arr2[i]; // They're different if c_xor != 0; the might be the same if c_xor == 0 return c_xor == 0;