2015-11-06 3 views
2

Я не знаю, как перетасовывать 2D-массив без дублирующих элементов. Может ли кто-нибудь помочь мне перетасовать 2D-массив?Перемешивание 2D-массива без использования коллекций

Вот то, что я до сих пор:

public class Shuffle2DArray 
{ 
    public Shuffle2DArray() 
    { 
    } 

    public static void Main(string[] args) 
    { 
     int[,] a = new int[3, 3] { { 1, 2, 3, }, { 6, 7, 8 }, { 11, 12, 13 } }; 

     Shuffle2DArray shuffle = new Shuffle2DArray(); 
     shuffle.getshuffle2D (a); 
    } 

    void getshuffle2D(int[,] arr) 
    { 
     Random ran = new Random(); 
     for (int i = 0; i < arr.GetLength (0); i++) { 

      for (int j = 0; j < arr.GetLength (1); j++) { 
       int m = ran.Next(arr.GetLength (0)-1); 
       int n = ran.Next(arr.GetLength (1)-1); 

       int temp = arr[0,j]; 
       arr[i,0] = arr[m,n+1]; 
       arr[m,n] = temp; 
       Console.Write(arr[i,j]+ "\t"); 
      } 
      Console.WriteLine(); 
     } 
    } 
} 
+1

[Fisher-Yates перетасовка] (https: // эн. wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) - это простой алгоритм перетасовки. Я предлагаю вам посмотреть на это. – Han

+0

В качестве побочного примечания, возможно, именно так вы помещаете свой код здесь, но вы должны извлечь главный метод из своего тела класса и создать отдельный класс для этого – Icepickle

ответ

1

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

Посмотрите на этот алгоритм сортировки для массива 1d.

for (int i = 0; i < arr.Length - 1; i++) 
{ 
    for (int j = i + 1; j < arr.Length; j++) 
    { 
     if (arr[i] > arr[j]) // ran.Next(-1,1) == 0 // or any random condition 
     { 
      int temp = arr[i]; 
      arr[j] = arr[i]; 
      arr[i] = temp; 
     } 
    } 
} 

Как вы можете видеть, нам нужно 2 цикла для сортировки 1-го массива. Поэтому для сортировки массива 2d нам нужно 4 петли.

for (int i = 0; i < arr.GetLength(0); i++) 
{ 
    for (int j = 0; j < arr.GetLength(0); j++) 
    { 
     for (int k = 0; k < arr.GetLength(1); k++) 
     { 
      for (int l = 0; l < arr.GetLength(1); l++) 
      { 
       if (arr[i, k] > arr[j, l]) // ran.Next(-1,1) == 0 
       { 
        int temp = arr[i, k]; 
        arr[i, k] = arr[j, l]; 
        arr[j, l] = temp; 
       } 
      } 
     } 
    } 
} 

Затем напишите еще один алгоритм для печати элементов.

for (int i = 0; i < arr.GetLength(0); i++) 
{ 
    for (int j = 0; j < arr.GetLength(1); j++) 
    { 
     Console.Write(arr[i, j] + "\t"); 
    } 
    Console.WriteLine(); 
} 

Это алгоритм сортировки. Теперь, если вы просто изменяете это условие со случайным, вы сортируете массив произвольным образом.

Изменить if (arr[i, k] > arr[j, l])

Для if (ran.Next(-1,1) == 0). это просто случайно или ложно.

1

Ну, я бы сказал, перетасовываем массив 2d так же, как вы перетасовываете 1-й массив.

Например, Fisher–Yates shuffle для 1d массива то вроде этого

public static class Utils 
{ 
    public static void Swap<T>(ref T a, ref T b) { var temp = a; a = b; b = temp; } 
    public static void RandomShuffle<T>(this T[] target, Random random = null) 
    { 
     if (target.Length < 2) return; 
     if (random == null) random = new Random(); 
     for (int i = target.Length - 1; i > 0; i--) 
     { 
      int j = random.Next(i + 1); 
      if (i != j) Swap(ref target[i], ref target[j]); 
     } 
    } 
} 

Все, что вам нужно, это осознать, что наличие 2d массив

T [,] массив

и доступа к элементу массива

массив [строка, столбец]

, что

строка = индекс/ColumnCount

колонка = индекс% ColumnCount

где

индекс = [0, arr ay.Lenght - 1] соответствует индексу в массиве 1d

columnCount = массив.GetLength (1)

добавления 2d функцию версии к классу выше тривиальна

public static class Utils 
{ 
    // ... 
    public static void RandomShuffle<T>(this T[,] target, Random random = null) 
    { 
     if (target.Length < 2) return; 
     if (random == null) random = new Random(); 
     int columnCount = target.GetLength(1); 
     for (int i = target.Length - 1; i > 0; i--) 
     { 
      int j = random.Next(i + 1); 
      if (i != j) Swap(ref target[i/columnCount, i % columnCount], ref target[j/columnCount, j % columnCount]); 
     } 
    } 
} 

Пример использования:

int[,] a = new int[3, 3] { { 1, 2, 3, }, { 6, 7, 8 }, { 11, 12, 13 } }; 
a.RandomShuffle(); 
+0

с хорошим решением O (n)! –

+0

@ M.kazemAggary Большое спасибо! Но я ничего здесь не придумал :-) –

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