【问题标题】:Java, How to check if two 2d arrays contain the same valuesJava,如何检查两个二维数组是否包含相同的值
【发布时间】:2012-06-13 22:26:32
【问题描述】:

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

【问题讨论】:

  • 查看 API,尤其是 java.util.Arrays 类,了解有用的方法。
  • 有不止一种方法可以做到这一点。您正在寻找效率吗?因为我会遍历一个数组并检查每个值。如果有东西存在,请继续。如果不是,则中断循环并抛出错误/消息
  • 这不是家庭作业...我尝试这样做但我没有成功...我尝试了api,我没有找到可以帮助我的东西...
  • 如果第一个数组中有一行 [1,2,3,4,5] 而第二个数组中有行 [1,2,3,4,10] 怎么办?数组可以相等还是因为行不包含相同的数字数组不能相等?

标签: java arrays multidimensional-array


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    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
    

    【讨论】:

      【解决方案3】:

      我建议您先对这些数组进行排序。如果您不想移动这些值,您可以简单地创建现有数组的副本并使用这些副本。

      这是我解决这个问题的代码:(它在不使用列表的情况下进行排序)

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

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        这是 MaxMackie 建议的示例。我正在将数组转换为列表,因为要比较 2x 2d 数组,您需要 4 个周期,第一个数组需要 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");
        }
        

        【讨论】:

        • 它不会对我返回真实的,例如
        【解决方案5】:

        如果您需要一种非常有效的算法来确定列表/数组等价,其中两个列表/数组包含相同数量的项目但不一定以相同的顺序,请尝试以下算法。我是从thisstackoverflow question/answers 中学到的,很棒!

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-07-10
          • 2017-11-24
          • 1970-01-01
          相关资源
          最近更新 更多