检查两个数组的值是否相等且顺序相同

我卡在了一个特定的逻辑上。我有两个数组,我需要检查这两个数组的值是否相等且顺序相同。循环也是允许的。比如:

array1 = {4, 3, 2, 1}
array2 = {1, 4, 3, 2} -- true.

array1 = {4, 3, 2, 1}
array2 = {2, 1, 4, 3} -- true.

数组值允许重复。我不能排序数组,因为允许有重复的值,排序会弄乱数组的顺序。

原文链接 https://stackoverflow.com/questions/41073468

点赞
stackoverflow用户7098806
stackoverflow用户7098806

代码:

import java.util.ArrayList;
import java.util.Arrays;

public class ArrayComparison {

    // 创建数组
    private static int[] array1 = new int[] {2,3,4,7,1};
    private static int[] array2 = new int[] {2,3,4,7,1};
    private static int[] array3 = new int[] {1,7,4,2,3};
    private static int[] array4 = new int[] {1,2,3,4,5,6,7,8,9};
    private static int[] array5 = new int[] {2,3,4,5,1};

    public static void main(String args[]){
        System.out.println(compareArrays(array1, array2));  // True
        System.out.println(compareArrays(array1, array3));  // True
        System.out.println(compareArrays(array1, array4));  // False
        System.out.println(compareArrays(array1, array5));  // False
    }

    /**
     * Compares if a1 is equal than a2, no matter the order
     * @param a1 Array 1
     * @param a2 Array 2
     * @return True if a1 == a2, false if a1 != a2. no matter the order
     */
    private static boolean compareArrays(int[] a1, int[] a2){
        boolean areEqual=false;
        // 克隆数组
        int[] a1Aux = a1.clone();
        int[] a2Aux = a2.clone();
        // 排序
        Arrays.sort(a1Aux);
        Arrays.sort(a2Aux);
        // 比较
        if(a1Aux.length == a2Aux.length){
            for(int i=0;i<a1Aux.length;i++){
                if(a1Aux[i] != a2Aux[i]){
                    return areEqual;
                }
            }
            return true;
        }
        return areEqual;
    }
}

输出:

true
true
false
false
2016-12-10 08:35:21
stackoverflow用户7121505
stackoverflow用户7121505

你可以编写嵌套循环,但让我们想一想不同的方法。如果我们将第二个数组附加到自身,我们只需要在第二个数组上执行第一个数组的 "indexOf" 操作。这里是一些未经测试的代码,显示了这个想法:

public static boolean arraysMatch(int[] array1, int[] array2) {
    int[] combined = new int[array2.length * 2];
    System.arraycopy(array2, 0, combined, 0, array2.length);
    System.arraycopy(array2, 0, combined, array2.length, array2.length);
    return Collections.indexOfSubList(Arrays.asList(combined), Arrays.asList(array1))!= -1;
}

或者更多地基于列表的方法:

public static boolean arraysMatch(int[] array1, int[] array2) {
    List<Integer> combined = new ArrayList<>(array2.length * 2);
    List<Integer> array2List = Arrays.asList(array2);
    combined.addAll(array2List);
    combined.addAll(array2List);
    return Collections.indexOfSubList(combined, Arrays.asList(array1))!= -1;
}

你可以循环而不复制数据,但是这是程序员时间与 CPU 时间之间的问题。

编辑:我知道答案已被采纳,但它仍然不完整。如果允许使用 Apache Commons Lang:[https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/ArrayUtils.html](https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/ArrayUtils.html)

public static boolean arraysMatch(int[] array1, int[] array2) {
    return Collections.indexOfSubList(
        Arrays.asList(ArrayUtils.toObject(ArrayUtils.addAll(array2, array2))),
        Arrays.asList(ArrayUtils.toObject(array1))
    )!= -1;
}
2016-12-10 09:06:28
stackoverflow用户5772882
stackoverflow用户5772882

这是直接的(但非常低效,涉及大量的复制)。我坚持使用 int 数组(没有列表或其他集合,没有 Integer 对象)。

public static boolean arraysWrappedEqual(int[] array1, int[] array2) {
    if (array1.length != array2.length) {
        return false;
    }
    for (int array2startIndex = 0; array2startIndex < array2.length; array2startIndex++) {
        // 比较 array1 的开头与 array2 的结尾以及反之
        int[] array1beginning = Arrays.copyOfRange(array1, 0, array1.length - array2startIndex);
        int[] array1end = Arrays.copyOfRange(array1, array1.length - array2startIndex, array1.length);
        int[] array2beginning = Arrays.copyOfRange(array2, 0, array2startIndex);
        int[] array2end = Arrays.copyOfRange(array2, array2startIndex, array2.length);
        if (Arrays.equals(array1beginning, array2end) && Arrays.equals(array1end, array2beginning)) {
            return true;
        }
    }
    return false;
}

对于问题中的两种情况都返回 true。

2016-12-10 09:25:56