2013-07-14 3 views
0

Я пытаюсь написать код, который заполнит массив уникальными номерами.заполнение многомерного массива с уникальными номерами в C#

Я мог написать код отдельно для 1, 2 и 3 мерных массивов, но число циклов for выросло до «бесконечности».

это код для 2D массива:

static void fillArray(int[,] array) 
     { 
      Random rand = new Random(); 

      for (int i = 0; i < array.GetLength(0); i++) 
      { 
       for (int j = 0; j < array.GetLength(1); j++) 
       { 
        array[i, j] = rand.Next(1, 100); 
        for (int k = 0; k < j; k++) 
         if (array[i, k] == array[i, j]) 
          j--; 
       } 
      } 

      print_info(array); 
     } 

Можно ли сделать что-то подобное для п мерных массивов?

+0

Ваш код проверяет только то, что число уникально в пределах одного и того же фрагмента массива. Это намерение, или число должно быть уникальным во всем массиве? – Guffa

+0

взлеты. Я этого никогда не замечал. Ты прав. Он должен быть уникальным во всем массиве. – mishonacro

ответ

0

Мой подход состоит в том, чтобы начать с 1-го массива уникальных чисел, которые вы можете перетасовать, а затем сложить в соответствующие места в вашем реальном массиве.

Вот основные функции:

private static void Initialize(Array array) 
{ 
    var rank = array.Rank; 
    var dimensionLengths = new List<int>(); 
    var totalSize = 1; 
    int[] arrayIndices = new int[rank]; 

    for (var dimension = 0; dimension < rank; dimension++) 
    { 
     var upperBound = array.GetLength(dimension); 
     dimensionLengths.Add(upperBound); 
     totalSize *= upperBound; 
    } 

    var singleArray = new int[totalSize]; 
    for (int i = 0; i < totalSize; i++) singleArray[i] = i; 
    singleArray = Shuffle(singleArray); 

    for (var i = 0; i < singleArray.Length; i++) 
    { 
     var remainingIndex = i; 
     for (var dimension = array.Rank - 1; dimension >= 0; dimension--) 
     { 
      arrayIndices[dimension] = remainingIndex%dimensionLengths[dimension]; 
      remainingIndex /= dimensionLengths[dimension]; 
     } 

     // Now, set the appropriate cell in your real array: 
     array.SetValue(singleArray[i], arrayIndices); 
    } 
} 

Ключ в этом примере является array.SetValue(value, params int[] indices) функция. Создав правильный список индексов, вы можете использовать эту функцию для установки произвольной ячейки в вашем массиве.

Вот Shuffle функция:

private static int[] Shuffle(int[] singleArray) 
{ 
    var random = new Random(); 
    for (int i = singleArray.Length; i > 1; i--) 
    { 
     // Pick random element to swap. 
     int j = random.Next(i); // 0 <= j <= i-1 
     // Swap. 
     int tmp = singleArray[j]; 
     singleArray[j] = singleArray[i - 1]; 
     singleArray[i - 1] = tmp; 
    } 
    return singleArray; 
} 

И, наконец, демонстрация ее в использовании:

var array1 = new int[2,3,5]; 
Initialize(array1); 
var array2 = new int[2,2,3,4]; 
Initialize(array2); 

Моя стратегия присваивает порядковые номера к первоначальному 1-й массив, чтобы обеспечить уникальность, но вы можете принять другую стратегию для этого, как вы сочтете нужным.

0

Вы можете использовать Rank свойство, чтобы получить общее количество габаритов в массиве

Для вставки Используйте SetValue метода

+0

Я проверю это. Благодарю. – mishonacro

0

В первых двух для петель вы анализирующие массив правильно (i и j перейти от начало до конца соответствующего измерения). Проблема возникает в самой внутренней части, где вы вводите «исправление», которое фактически вызывает бесконечный цикл для j.

First iteration: 
- First loop: i = 0; 
- Second loop: j = 0; 
- Third loop: j = -1 

Second iteration 
- First loop: i = 0; 
- Second loop: j = 0; 
- Third loop: j = -1 
. etc., etc. 

(я начинаю свой анализ в тот момент, когда внутренний цикл используется в первый раз. Кроме того, иметь в виду, что точное поведение не может быть предсказано, насколько случайные числа участников. Но идея состоит в том, что вы делаете счетчик j снова и снова, следуя произвольному правилу).

Что именно вы хотите достичь? Какая последняя коррекция (вызывающая бесконечный цикл)?

Если единственное, что вы собираетесь сделать, это проверить ранее сохраненные значения, вы должны полагаться на другой переменной (j2, например), которые не будут затрагивать любую из петель выше:

int j2 = j; 
    for (int k = 0; k < j2; k++) 
     if (array[i, k] == array[i, j2]) 
     j2--; 
Смежные вопросы