检查两个数组是否具有相同顺序的元素

时间:2014-11-06 00:14:54

标签: java arrays

如何检查两个数组(循环)是否具有相同顺序的相同元素。 例如,让我们取数组[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>

还有更好的方法吗? 谢谢。

4 个答案:

答案 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;
}

如果允许重复,您必须考虑到i1i2可以从不同的点开始并尝试所有这些,如果最后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");
    }