как создать случайный 2d массив в C со значениями, повторяющимися только дважды - PullRequest
0 голосов
/ 03 ноября 2010

Я очень плохо знаком с программированием на c и сделал только if / else, циклы, массивы, указатели, функции и структуры.Я был бы очень рад, если бы кто-нибудь мог сказать мне, как создать двумерный массив, который содержал бы рандомизированный со временем, но имел бы значения, которые повторяются только дважды ...

значение, например:

1 2 3 6
8 7 4 5
7 5 6 3
2 1 4 8

на самом деле мне нужно, чтобы массив был 6x6, и до сих пор я дошел до этой стадии, которая не работает:

int x,y;
int i,j;

srand (time(NULL));

for ( x=0 ; x<6 ; x++){
    for ( y=0 ; y<6 ; y++) {
        sBoard[x][y] = rand() %36;          /*randomization*/

        for ( i=0 ; i<6 ; i++){  /*trying to create an unique array*/
            for ( j=0 ; j<6 ; j++) {
                if ((sBoard[x][y] == sBoard[i][j])) {
                    x--;
                    y--;
                }
            }
        }
        printf ("%i",sBoard[x][y]);
    }
    printf("\n");
}

======================================================================================= мой лектор попросил меня попробовать и использовать функцию if, чтобы проверить, повторяется ли значение где-либо еще в матрице ... то естьпочему я использую «если» ... я был бы очень признателен, если бы вы могли мне помочь ... заранее спасибо ...

Ответы [ 4 ]

1 голос
/ 03 ноября 2010

Проблема в том, что ваш блок if-then по-прежнему не гарантирует такой уровень уникальности. Вам нужно было бы использовать цикл while, чтобы это работало правильно. Цикл while теоретически никогда не может завершиться, и (что более вероятно) для его выполнения потребуется значительно разное время при каждом запуске.

Что может быть намного проще, это заполнить двумерный массив всеми значениями, а затем перемешать ТО. Вы можете обмануть и рассматривать его как 1-й массив, и он все равно будет работать так же. Вот некоторый псевдокод:

pointer-to-array pArray;
for i = 0 to 35
    pArray[i] = i
numShuffle = 2;
for s = 1 to numShuffle
    for i = 0 to 35
        swap pArray[i] with pArray[random 0 to 34 - if equal, add 1]

Это гарантирует, что дубликатов не существует, и выполнение вашего кода всегда будет занимать одинаковое количество времени (вместо того, чтобы цикл while, который я упоминал выше, потенциально никогда не завершался).

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

0 голосов
/ 03 ноября 2010

Первое, что случайное не исключает повторения само по себе - случайное распределение - это просто случайное распределение, которое не имеет равномерно распределенного множества, что означает, что ни один элемент больше не встречается. Поэтому я бы начал (для простоты) сглаживая массив 6x6 2d в массив 36x 1d, а затем реорганизовав его позже.

Таким образом, используя массив 1d, вы можете циклически проходить, и для каждой позиции в цикле do генерировать случайное число, а затем вы можете иметь внутренний цикл for, который перебирает существующий массив от 0 до текущей позиции. и если случайное число видно в одной из этих позиций, отметьте флаг, чтобы сказать, что оно уже было замечено. Таким образом, вы можете завершить цикл do с помощью while (notUnique).

Хорошо - покажи мне код!

int board1d[36];
int pos;
for(pos = 0; pos < 36; pos ++) {
  int newRand;
  int notUnique;
  do {
    int innerPos;
    notUnique = 0;
    newRand = rand() % 36;
    for(innerPos = pos; innerPos > 0 && notUnique==0; innerPos--) {
      notUnique = (newRand == board1d[innerPos]);
    }
  } while(notUnique);
  board1d[pos] = newRand;
}

Это, как упоминалось выше, потенциально означает, что если генератор случайных чисел генерирует повторяющуюся последовательность, то цикл будет занимать больше циклов. Не существует гарантированного равномерного распределения в случайном наборе.

0 голосов
/ 03 ноября 2010

Меня немного смущает следующее: Разрешено ли 2-му массиву (а) содержать конкретное значение дважды как максимум или (б) должен ли 2-мерный массив содержать каждое значение ровно дважды все время?

(a): Создайте вспомогательный массив, содержащий все разрешенные значения дважды каждый. Затем сгенерируйте случайное число в качестве индекса для этого вспомогательного массива, чтобы выбрать одно из чисел в нем и сохранить его в «следующей» позиции желаемого 2d-массива. Не забудьте удалить выбранное значение из вспомогательного массива.

(b): Первоначально вы могли создать массив 6x6, содержащий все значения от 1 до 18 дважды каждое. Затем просто перемешайте значения, меняя местами два значения за одну итерацию.

edit : Относительно вашего собственного подхода и некоторых других предложений по решению: я думаю, что метод проб и ошибок - не лучший способ гарантировать, что каждое значение сохраняется (только) дважды. Потому что теоретически это может привести к бесконечному циклу. Да, я знаю, это вряд ли произойдет, но, на мой взгляд, оно немного грязное. Я бы предпочел решение с детерминированным / постоянным временем выполнения, предотвращающее ненужные операции.

0 голосов
/ 03 ноября 2010

Каков диапазон допустимых значений? Предположим, что он не слишком большой, немного N, я бы предложил следующий алгоритм:

  • Инициализировать seen как массив из N int счетчиков, определяя, сколько раз было сгенерировано каждое значение.
  • Перейдите к целевому 2D-массиву, сгенерируйте число num с помощью rand.
    • Если seen[num] равно 2, сгенерируйте num и попробуйте снова
    • В противном случае увеличьте seen[num] и поместите num в его слот в массиве 2D

Естественно, seen должен быть инициализирован со всеми нулями.

Если диапазон чисел большой (скажем, весь диапазон целых чисел), я бы использовал хеш-таблицу вместо массива seen.

...