2012-06-10 2 views
3

Мне нужно проверить, имеют ли два 2-мерных массива [5][5] те же значения, даже если они перетасовываются.Java, Как проверить, содержат ли два массива 2d одинаковые значения

мне нужен способ, чтобы вернуть истину, если два массива содержат одни и те же значения, даже если, которые расположены по-другому, как:

  • 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

Что является лучшим способом, чтобы вернуться верно, когда оба имеют одинаковые значения?

+0

Ознакомьтесь с API и, в частности, классом java.util.Arrays для полезных методов. –

+0

Существует не один способ сделать это. Является ли эффективность той, что вы ищете? Потому что я бы прошел через один массив и проверял каждое значение по отношению к другому. Если что-то существует, продолжайте движение. Если нет, сломайте цикл и выбросите ошибку/сообщение – n0pe

+0

Это не работа на дому ... Я пытался это сделать, но мне не удалось ... И я попробовал api, я не нашел что-то, что могло бы помочь me ... – whiteberryapps

ответ

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 
0

Вот пример того, что предложил MaxMackie. Я преобразовываю массив в список, потому что для сравнения 2x 2d массивов вам понадобятся 4 цикла, 2 для 1-го массива и 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"); 
} 
+0

Это не вернет мне правду, например. – whiteberryapps

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

Надеется, что это помогает вам

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

Вы можете оптимизировать его дальше, прекомпиляции регулярного выражения, но в основном, вы должны получить эту идею.

Смежные вопросы