3

[5][5]1つがシャッフルされている場合でも、の2つの2次元配列に同じ値が含まれているかどうかを確認する必要があります。

次のように異なる方法で配置されている場合でも、2つの配列に同じ値が含まれている場合は、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を返すための最良の方法は何ですか?

4

5 に答える 5

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

正規表現を事前にコンパイルすることでさらに最適化できますが、基本的にはアイデアを得る必要があります。

于 2012-06-11T10:28:51.623 に答える
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
于 2012-06-10T23:49:26.250 に答える
0

リスト/配列の同等性を判断するための非常に効率的なアルゴリズムが必要な場合は、2つのリスト/配列に同じ数の項目が含まれているが、必ずしも同じ順序である必要はありません。以下のアルゴリズムを試してください。私はこのスタックオーバーフローの質問/回答からそれを学びました、そしてそれは素晴らしいです!

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;
}
于 2012-06-11T09:06:34.003 に答える
0

MaxMackie が提案した例を次に示します。2x 2d 配列を比較するには、最初の配列に 2 つ、2 番目の配列に 2 つの 4 サイクルが必要になるため、配列をリストに変換しています。

// 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");
}
于 2012-06-10T23:49:52.470 に答える