如何检查两个数组(循环)是否具有相同顺序的相同元素。 例如,让我们取数组[1,2,3,4]。
对于[2,3,4,1],[3,4,1,2],[4,1,2,3],测试应该返回true,但对于[1,3,2,4]则不然,[1,4,2,3]或[1,2,3,5]。
我最初的方法是找到第一个匹配 - 每个数组中的一个元素相等 - 并将这两个元素视为各自数组的初始元素,我逐个比较其余的数组元素。 / p>
还有更好的方法吗? 谢谢。
答案 0 :(得分:1)
如果数组是循环的,则array+array
具有另一部分的整个数组。
例如:
[2 3 4 1] append [2 3 4 1] = [2 3 4 1 2 3 4 1]
|-------|
你可以看到[1 2 3 4]
是"某处"在两次相同的数组附加。
因此,通过这种逻辑,您可以执行O(n*m)
操作,检查每个案例是否匹配(n为array1,m为array2):
//array1 has [2 3 4 1 2 3 4 1]
//array2 has [1 2 3 4]
boolean check = false;
for(int i = 0; i < array1.length(); i++) {
for(int j; j < array2.length(); j++) {
if((i+j) <= array1.length()) {
if(array1[i+j] == array2[j])
check = true;
else
check = false;
}
}
if(check)
return true; // returns true if all array2 == some part of array1
}
return false;
您还可以查看Boyer-Moore algorithm以改进此问题。它用于字符串匹配,但这里可以应用相同的逻辑。
基本思想是拥有一个array2的查找表,并且能够跳过&#34;跳过&#34;您知道的价值观不必再次检查。
1 2 3 4 5 6
3 4 5
^-------^ lookup table sees that the offset is 3 to match array2[0] with array1[2]
1 2 3 4 5 6
skip to--->3 4 5
would be the next iteration
答案 1 :(得分:0)
假设此算法可以为您提供帮助。
public void test() {
int[] a1 = {1,2,3,4};
int[] a2 = {2,3,4,5};
int[] a3 = {2,3,4,1};
if (calculateDifference(a1, a2)) {
System.out.println("a1 has same elements order to a2");
}
if (calculateDifference(a1, a3)) {
System.out.println("a1 has same elements order to a3");
}
if (calculateDifference(a2, a3)) {
System.out.println("a2 has same elements order to a3");
}
}
private boolean calculateDifference(int[] a1,int[] a2){
int total = 0;
boolean match = false;
if (a1.length != a2.length) {
return match;
}
for (int i = 0; i < a1.length; i++) {
int a1Num = a1[i];
int a2Num = a2[i];
total += a1Num - a2Num;
}
if (total == 0) {
match = true;
}
return match;
}
答案 2 :(得分:0)
如果不允许重复,你只需要在第二个数组中找到另一个元素,等于第一个数组的第一个,并从那里检查它们,解决方案是O(n):
boolean areEquivalent(int[] array1, int[] array2) {
int i1 = 0, i2 = 0;
for (; i2 < array2.length; ++i2)
if (array2[i2] == array1[i1])
break;
// no element found in common, they can't be equivalent
if (i2 == array2.length)
return false;
for (int j = 0; j < array1.length; ++j)
if (array1[i1+j] != array2[(i2+j) % array2.length]
return false;
return true;
}
如果允许重复,您必须考虑到i1
和i2
可以从不同的点开始并尝试所有这些,如果最后for
失败,您应该更改{{ 1}}从第二次出现的相同值开始,依此类推。完成此操作后,您必须再次更改i1
重试,因此不同的方法(如Jay提出的方法)可以更好地工作。
答案 3 :(得分:0)
我尝试过这样做并且有效:
int a[] = {2,3,4,1};
int b[] = {3,4,1,2}; // return true for these input
boolean check = false;
for (int i = 0; i < a.length; i++) {
int tmp = b[0];
System.arraycopy(b, 1, b, 0, b.length - 1);
b[b.length - 1] = tmp;
if (Arrays.equals(a, b)) {
check = true;
System.out.println("Output: " + Arrays.equals(a, b));
}
}
if (!check) {
System.out.println("Output: false");
}