簡體   English   中英

相同的數組元素

[英]Same Array Elements

我想檢查一個數組中的所有元素是否與另一個數組中的所有元素相同,即一對一匹配。 (注意:兩個數組元素的順序不會相同)

有沒有一種快速的方法,或者我可以使用一個預先存在的庫?

目前,我能想到的兩種方法並不理想:

一對一匹配 (編輯3:此示例是錯誤的,不能滿足重復要求)

    boolean exactMatch = true;
    if(strList1.size() == strList2.size()){
        for(String str: StrList1){
            if(!strList2.contains(str)){
                exactMatch = false;
                break;
            }
        }
    }

排序然后匹配 (更優化,尤其適用於大型數組)

    strList1 = Arrays.sort(strList1);
    strList2 = Arrays.sort(strList2);

    boolean exactMatch = true;
    if(strList1.size() == strList2.size()){
        for (int i = 0; i < strList1.length; i++) {
            if(!strList1[i].equals(strList2[i])){
                exactMatch = false;
                break;
            }
        }
    }

編輯1

感謝那些發表評論的人。 數組元素的順序不相同。 即,以下內容將返回false:

String[] strList1 = {"ABC", "CDE", "EFG"};
String[] strList2 = {"ABC", "EFG", "CDE"};
System.out.println("array equals " + Arrays.deepEquals(strList1, strList2));

編輯2

我遺漏的一個好點是,“ myusuf”指出的是陣列中的重復項。 這意味着我的“一對一匹配”示例將不起作用。 以這個為例:

public static void main(String[] args) {
    String[] strList1 = {"ABC", "CDE", "EFG", "ABC"};
    String[] strList2 = {"ABC", "EFG", "CDE", "CDE"};
    System.out.println(arrayEquals(strList1,strList2));
}
private static boolean arrayEquals(String[] array1, String[] array2) {
    List<String> list1 = Arrays.asList(array1);
    List<String> list2 = Arrays.asList(array2);
    return list1.containsAll(list2) && list2.containsAll(list1);
}

在這種情況下,strList1具有“ ABC”的重復項,而strList2具有“ CDE”的重復項,但是它們仍然匹配,因為當數組本身不同時,它們的唯一元素仍然相同。


編輯3

謝謝大家的回答。 因此,經過反復的反復,似乎最簡單的方法是:

    String[] strList1 = {"ABC", "CDE", "EFG", "CDE", "EFG"};
    String[] strList2 = {"ABC", "EFG", "CDE", "EFG", "CDE"};

    Arrays.sort(strList1);
    Arrays.sort(strList2);
    boolean exactMatch = Arrays.deepEquals(strList1, strList2);

    System.out.println("test3 - match: " + exactMatch);

我希望有一個方法調用可以完成所有任務,但是看來已經完成了。 如果所有元素的順序不同,則Arrays.deepEquals()僅適用於排序數組。 使用contains()的方法不起作用,因為存在重復項。

Arrays#deepEquals(java.lang.Object[], java.lang.Object[])

它提供了兩個數組引用,它們被視為深度相等或不相等。

Arrays.deepEquals(e1,e2);

如果滿足以下任一條件,則兩個可能為null的元素e1和e2完全相等:

  - e1 and e2 are both arrays of object reference types, and Arrays.deepEquals(e1, e2) would return true - e1 and e2 are arrays of the same primitive type, and the appropriate overloading of Arrays.equals(e1, e2) would return true. - e1 == e2 - e1.equals(e2) would return true. Note that this definition permits null elements at any depth. 

文獻資料

Arrays#equals(Object[],Object[])方法不同,此方法適用於任意深度的嵌套數組。

使用Arrays.equals

Arrays.equals(ary, ary2));

Arrays.deepEquals

如果兩個指定的數組彼此深度相等,則返回true。 與@link {#equals {Object [],Object [])方法不同,此方法適用於任意深度的嵌套數組。 如果兩個數組引用都為null,或者兩個數組引用都引用了包含相同數量元素的數組,並且兩個數組中所有對應的元素對都非常相等,則認為它們是完全相等的。

如果滿足以下任一條件,則兩個可能為null的元素e1和e2完全相等:

e1和e2都是對象引用類型的數組,並且Arrays.deepEquals(e1, e2)將返回true
e1和e2是相同原始類型的數組,並且Arrays.equals(e1, e2)的適當重載將返回true
e1 == e2
e1.equals(e2)將返回true。

public static boolean equals(int[] a, int[] a2)

如果兩個指定的int數組彼此相等,則返回true。 如果兩個數組包含相同數量的元素,並且兩個數組中所有對應的元素對相等,則認為兩個數組相等。 換句話說,如果兩個數組包含相同順序的相同元素,則它們相等。 另外,如果兩個數組引用都為空,則認為它們相等。

您可以使用列表removeAll方法

strList2.removeAll(strList1)

if(strList2.isEmpty)
{
  // Exact match
}
else{

  // failed
}

您可以使用哈希映射。 此方法的時間復雜度較低,因為不需要排序和搜索,但是由於使用了哈希圖,因此空間復雜度較高:

        String[] strList1 = {"ABC", "CDE", "EFG"};
        String[] strList2 = {"ABC", "EFG", "CDE"};
        Boolean flag = true;
        Map<String, Integer> map = new HashMap<String, Integer>();

        /*Initial Check*/

        if(strList1.length != strList2.length) {
           System.out.print("Array equals: false");
           return 0;
        }

        /*Add all strings from list1 and their frequency to map*/

        for(int i=0; i<strList1.length;i++) {
            if(map.get(strList1[i]) != null) 
               map.put(strList1[i], map.get(strList1[i]) + 1);
            else
               map.put(strList1[i], 0); 
        }

        /*If string found in map from list2, decrement count in map
          else list2 contains a string not in map, then arrays 
          unequal as list2 contains a string not in list1*/

        for(int i=0; i<strList2.length;i++) {
            if(map.get(strList2[i]) != null)
               map.put(strList2[i], map.get(strList2[i]) - 1);
            else {  
                System.out.print("Array equals: false");
                flag = false;
            }
        }

        /*If map contains the same value for every string i.e. 0, then they occur
          equal no. of times in both arrays. Hence, Set values will contain 
          only one value so (values.size() == 1) will be equal true, else false*/

        if(flag) {
            Set<Integer> values = new HashSet<Integer>(map.values());
            System.out.print("Array equals: " + (values.size() == 1));
        }
        return 0;

對於您的輸入,這將輸出: Array equals: true
此方法還考慮了輸入數組中的重復字符串。

這將是您的問題的簡短解決方案。 我敢肯定,還有更多高效但復雜的方法可以做到這一點。 在這里, arrayEquals將您的數組轉換為List並使用List.containsAll檢查是否相等。

public class ArrayEquality {
    public static void main(String[] args) {
        String[] array1 = {"test1","test2"};
        String[] array2 = {"test2","test1"};
        String[] array3 = {"test2","test3"};

        String[] strList1 = {"ABC", "CDE", "EFG"};
        String[] strList2 = {"ABC", "EFG", "CDE"};

        System.out.println(arrayEquals(array1,array2));
        System.out.println(arrayEquals(array2,array3));

        System.out.println(arrayEquals(strList1,strList2));
    }

    //ARRAY EQUALITY CHECK
    private static boolean arrayEquals(String[] array1, String[] array2) {
        List<String> list1 = Arrays.asList(array1);
        List<String> list2 = Arrays.asList(array2);

        return list1.containsAll(list2) && list2.containsAll(list1);
    }
}

為了處理此解決方案數組中的重復項,可以像這樣更改等於

private static boolean arrayEquals(String[] array1, String[] array2) {
List<String> list1 = Arrays.asList(array1);
List<String> list2 = Arrays.asList(array2);

Collections.sort (list1);
Collections.sort (list2);
return list1.equals(list2);
}

可以通過大小檢查來優化它以避免排序。

您可以為此使用以下內容:

String[] strArray1;
String[] strArray2;

我改名為他們strArray而不是strList為logicalness,則:

private <T> boolean containsAll(final T[] a1, final T[] a2) {
    return Arrays.asList(a1).containsAll(Arrays.asList(a2));
}

並調用:

boolean exactMath = containsAll(strArray1, strArray2) 
        && containsAll(strArray2, strArray1);

請注意, Arrays.asList(T[] array)只是在T[] array周圍創建一個List<T> 包裝 ,它實際上並沒有復制T[] array 如果修改了List<T>將修改所述背襯T[] array

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM