Если у вас есть матрица 3x2, которая должна быть заполнена цифрами/цифрами 1, 1, 2, 2, 3, 3 в некоторой случайной перестановке, вы можете сделать что-то вроде:
- Выделите массив (вектор) нужного размера — 6 для текущего примера.
- Заполните массив правильными значениями — 1, 1, 2, 2, 3, 3 для текущего примера.
- Используйте соответствующий метод для перетасовки массива, а затем скопируйте перетасованные данные в целевой двумерный массив.
- Или выбрать случайным образом цифру из начальных 6 вариантов, затем (при необходимости) переместить последнюю цифру в отверстие и выбрать следующую цифру из оставшихся 5 вариантов и т.д.
Вы можете использовать алгоритм перетасовки Fisher-Yates. Вы можете проверить свою копию книги Кнута The Art of Computer Programming, Том 2: Получисловые алгоритмы. Или вы можете поискать описания в Stack Overflow (например, алгоритм для выберите одну случайную комбинацию значений, выбранную потому, что она также была обнаружена в одном из моих поисковых запросов Google).
Судя по комментариям, вам нужны дубликаты вашего суррогата rand()
, так что это должно работать:
int duprand(void)
{
static int mode = 0;
static int value = 0;
if (mode == 0)
{
mode = 1;
value = rand();
}
else
{
mode = 0;
}
return value;
}
Или, более кратко:
int duprand(void)
{
static int mode = 0;
static int value = 0;
if (mode == 0)
value = rand();
mode = !mode;
return value;
}
Просто звоните duprand()
каждый раз, когда вам нужен случайный номер. Вы получите одно и то же значение дважды подряд. Этот код не предоставляет метод ресинхронизации; если вы хотите, вы можете написать его достаточно легко:
void sync_duprand(void)
{
int i = duprand();
int j = duprand();
if (i != j)
i = duprand();
}
Чего я действительно хотел, так это...
#include <stdio.h>
#include <stdlib.h>
extern void shuffle(int *array, int n);
/*
** rand_int() and shuffle() copied verbatim (but reformatted) from
** https://stackoverflow.com/a/3348142 - an answer by Roland Illig
** (https://stackoverflow.com/users/225757/roland-illig).
*/
static int rand_int(int n)
{
int limit = RAND_MAX - RAND_MAX % n;
int rnd;
do
{
rnd = rand();
} while (rnd >= limit);
return rnd % n;
}
void shuffle(int *array, int n)
{
int i, j, tmp;
for (i = n - 1; i > 0; i--)
{
j = rand_int(i + 1);
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
}
}
/* New code - but hardly novel code */
static void dump_matriz(int matriz[4][4])
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
printf(" %d", matriz[i][j]);
putchar('\n');
}
}
int main(void)
{
int matriz[4][4];
int *base = &matriz[0][0];
for (int i = 0; i < 8; i++)
{
*base++ = i + 1;
*base++ = i + 1;
}
printf("Before:\n");
dump_matriz(matriz);
shuffle(&matriz[0][0], 16);
printf("After:\n");
dump_matriz(matriz);
return 0;
}
Пример вывода:
Before:
1 1 2 2
3 3 4 4
5 5 6 6
7 7 8 8
After:
1 7 8 6
6 2 5 8
2 4 7 3
3 5 1 4
Обратите внимание, что из-за отсутствия вызова srand()
перестановка фиксирована. (Вы можете получить результат, отличный от того, что я показываю, но выполнение этого теста несколько раз будет давать один и тот же результат на вашем компьютере каждый раз.) Добавьте вызов srand()
с соответствующей инициализацией, и вы получите разные последовательности. Рубите и измельчайте в соответствии с вашими требованиями для меньших матриц.
person
Jonathan Leffler
schedule
22.06.2015