Java,如何检查两个2d数组是否包含相同的值

时间:2012-06-10 22:44:50

标签: java arrays multidimensional-array

我需要检查[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的最佳方法是什么?

5 个答案:

答案 0 :(得分:3)

这是我的解决方案。使用起来相当简单。

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("[\\[\\], ]", "")));
        }
    });
}

您可以通过预编译正则表达式来进一步优化它,但基本上,您应该明白这一点。

答案 1 :(得分:1)

如果行中的数据相同但无关紧要,我们可以将数组中的所有数字存储到单独的列表中然后进行比较。

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

答案 2 :(得分:1)

我建议你先排序这些数组。如果您不想移动值,您只需创建现有数组的副本并使用副本。

这是我的问题代码:(不使用列表排序)

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

希望这有助于你

答案 3 :(得分:0)

这是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");
}

答案 4 :(得分:0)

如果您需要一种非常有效的算法来确定列表/数组等效,其中两个列表/数组包含相同数量的项目,但不一定按相同的顺序排列,请尝试以下算法。我是从this堆栈溢出问题/答案中学到的,这很棒!

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