簡體   English   中英

Java,如何檢查兩個2d數組是否包含相同的值

[英]Java, How to check if two 2d arrays contain the same values

我需要檢查[5][5]兩個二維數組是否包含相同的值,即使其中一個被洗牌。

如果兩個數組包含相同的值,我需要該方法返回true,即使它以不同的方式排列,如:

  • 1,2,3,4,5
  • 6,7,8,9,10
  • 11,12,13,14,15
  • 16,17,18,19,20-
  • 21,22,23,24,25

和:

  • 25,24,23,22,21
  • 1,2,3,4,5,
  • 7,8,9,10,6
  • 20,19,18,17,16
  • 15,14,13,12,11

當兩者具有相同的值時,返回true的最佳方法是什么?

這是我的解決方案。 使用起來相當簡單。

int[][] array1 = {
    {1,2,3,4,5},
    {6,7,8,9,10},
    {11,12,13,14,15},
    {16,17,18,19,20},
    {21,22,23,24,25}
};

int[][] array2 = {
    {25,24,23,22,21},
    {1,2,3,4,5},
    {7,8,9,10,6},
    {20,19,18,17,16},
    {15,14,13,12,11}
};

sort2D(array1);
sort2D(array2);

System.out.println(Arrays.deepEquals(array1, array2));

在這種情況下哪個打印true

sort2D方法實現如下:

public static void sort2D(int[][] array) {
    for (int[] arr : array) {
        Arrays.sort(arr);
    }

    Arrays.sort(array, new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
            return new BigInteger(Arrays.toString(o1).replaceAll("[\\[\\], ]", ""))
                .compareTo(new BigInteger(Arrays.toString(o2).replaceAll("[\\[\\], ]", "")));
        }
    });
}

您可以通過預編譯正則表達式進一步優化它,但基本上,您應該明白這一點。

如果行中的數據相同但無關緊要,我們可以將數組中的所有數字存儲到單獨的列表中然后進行比較。

int[][] a1 = { { 1, 2 }, { 3, 4 } };
int[][] a2 = { { 4, 3 }, { 2, 1 } };

//lists to store arrays data
List<Integer> list1 = new ArrayList<Integer>();
List<Integer> list2 = new ArrayList<Integer>();

//lest place data from arrays to lists
for (int[] tmp:a1)
    for (int i:tmp)
        list1.add(i);

for (int[] tmp:a2)
    for (int i:tmp)
        list2.add(i);

//now we need to sort lists
Collections.sort(list1);
Collections.sort(list2);

//now we can compare lists on few ways

//1 by Arrays.equals using list.toArray() 
System.out.println(Arrays.equals(list1.toArray(), list2.toArray()));
//2 using String representation of List
System.out.println(list1.toString().equals(list2.toString()));
//3 using containsAll from List object
if (list1.containsAll(list2) && list2.containsAll(list1))
    System.out.println(true);
else 
    System.out.println(false);

//and many other probably better ways

如果行也必須包含相同的數字(但可以像[1,2] [2,1]那樣混洗,但不像[1,2] [1,3]那樣)你可以做這樣的事情

// lets say i a1 and a2 are copies or original arrays 
int[][] a1 = { { 1, 2 }, { 3, 4 } };
int[][] a2 = { { 4, 3 }, { 2, 1 } };
System.out.println(Arrays.deepToString(a1));// [[1, 2], [3, 4]]
System.out.println(Arrays.deepToString(a2));// [[3, 4], [1, 2]]

// lets sort data in each row
for (int[] tmp : a1)
    Arrays.sort(tmp);
for (int[] tmp : a2)
    Arrays.sort(tmp);
System.out.println("========");
System.out.println(Arrays.deepToString(a1));// [[1, 2], [3, 4]]
System.out.println(Arrays.deepToString(a2));// [[3, 4], [1, 2]]

// Now I want to order rows by first stored number.
// To do that I will use Array.sort with this Comparator
Comparator<int[]> orderByFirsNumber = new Comparator<int[]>() {
    public int compare(int[] o1, int[] o2) {
        if (o1[0] > o2[0]) return 1;
        if (o1[0] < o2[0]) return -1;
        return 0;
    }
};

// lets sort rows by its first stored number
Arrays.sort(a1, orderByFirsNumber);
Arrays.sort(a2, orderByFirsNumber);

// i wonder how arrays look 
System.out.println("========");
System.out.println(Arrays.deepToString(a1));// [[1, 2], [3, 4]]
System.out.println(Arrays.deepToString(a2));// [[1, 2], [3, 4]]

System.out.println("Arrays.deepEquals(a1, a2)="
        + Arrays.deepEquals(a1, a2));

產量

[[1, 2], [3, 4]]
[[4, 3], [2, 1]]
========
[[1, 2], [3, 4]]
[[3, 4], [1, 2]]
========
[[1, 2], [3, 4]]
[[1, 2], [3, 4]]
Arrays.deepEquals(a1, a2)=true

我建議你先排序這些數組。 如果您不希望移動值,則只需創建現有陣列的副本並使用副本即可。

這是我的這個問題的代碼:(它沒有使用列表排序)

public class TwoDArraySort 
{
static int[][] arr1 = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}, {16,17,18,19,20}, {21,22,23,24,25}};
static int[][] arr2 = {{25,24,23,22,21}, {1,2,3,4,5}, {7,8,9,10,6}, {20,19,18,17,16}, {15,14,13,12,11}};

public static void main(String[]args) //The code below is meant to sort the second array
{
    int lowest;
    int switcher;
    int posX = -1;
    int posY = -1;

    for (int i=0; i<arr2.length; i++)
    {
        for (int z=0; z<arr2[i].length; z++)
        {
            lowest = arr2[i][z];

            for (int x=i; x<arr2.length; x++)
            {
                if (x == i)
                    for (int y=z; y<arr2[x].length; y++)
                    {
                        if (arr2[x][y] <= lowest)
                        {
                            lowest = arr2[x][y];
                            posX = x;
                            posY = y;
                        }
                    }
                else
                    for (int y=0; y<arr2[x].length; y++)
                    {
                        if (arr2[x][y] <= lowest)
                        {
                            lowest = arr2[x][y];
                            posX = x;
                            posY = y;
                        }
                    };
            }
            switcher = arr2[i][z];
            arr2[i][z] = arr2[posX][posY];
            arr2[posX][posY] = switcher; //Switches the lowest value to the first position that hasn't been changed already
        }
    }

    System.out.println(isSame(arr1, arr2)); //Calls the isSame method and print the returned boolean
}

//This method returns true if the arrays are the same
public static boolean isSame(int[][] arr1, int[][] arr2)
{
    for (int x=0; x<arr1.length; x++)
    {
        for (int y=0; y<arr1[x].length; y++)
        {
            if (arr1[x][y] != arr2[x][y])
            {
                return false;
            }
        }
    }

    return true;
}
}

希望這對你有所幫助

這是MaxMackie建議的一個例子。 我正在將數組轉換為列表,因為要比較2x 2d數組,你需要4個周期,2個用於第1個數組,2個用於第2個數組。

// to list
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        list1.add(array1[i][j]);
        list2.add(array2[i][j]);
    }
}

// comparing
boolean isInBoth;
for (int i = 0; i < 25; i++) { // 1st list
    isInBoth = false;
    for (int j = 0; j < 25; j++) { // 2nd list
        if (!isInBoth) { // if not found number in 2nd array yet
            if (list1.get(i) == list2.get(j)) { // if numbers are equal
                isInBoth = true; 
            }
        }
    }

    if (!isInBoth) { // if number wasn't in both lists
        return; 
    }
}

if (isInBoth) {
    System.out.println("Arrays are equal");
}

如果您需要一種非常有效的算法來確定列表/數組等效,其中兩個列表/數組包含相同數量的項目但不一定按相同的順序,請嘗試以下算法。 我從這個堆棧溢出問題/答案中學到了它, 太棒了!

boolean AreEquivalent(int[][] arrayOne, int[][] arrayTwo) {
  Dictionary<int, int> valueMap = new Dictionary<int, int>();

  // Add one for each occurrance of a given value in the first array
  for(int i=0; i<5; i++)
  for(int j=0; j<5; j++)
  {
    if (valueMap.containsKey(arrayOne[i][j]))
    {
      valueMap[arrayOne[i][j]]++;
    }
    else
    {
      valueMap[arrayOne[i][j]] = 1;
    }
  }

  // subtract one for each occurrance of a given value in the second array
  for(int i=0; i<5; i++)
  for(int j=0; j<5; j++)
  {
    if (valueMap.containsKey(arrayTwo[i][j]))
    {
      valueMap[arrayOne[i][j]]--;
    }
    else
    {
      // We can short circuit here because we have an item in the second
      // array that's not in the first array.
      return false;
    }
  }

  // now check the final tally, if not 0 the two arrays are not equivalent
  for (int tally: valueMap.values())
  {
    if (tally != 0)
    {
      return false;
    }
  }

  return true;
}

暫無
暫無

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

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