Другие языки программирования и технологии

Генерация уникальных чисел от 1 до 100 на С++

Добрый день.
Интересен такой вопрос. Надо заполнить матрицу 10х10, УНИКАЛЬНЫМИ случайными числами от 1 до 100. Вроде все это банально. И реализовал я с помощью двух массивов. Один двумерный - заполняем уникальными числами (это наш конечный массив) и второй одномерны (буфер) - куда мы записываем те же уникальные значения с целью проверки очередного сгенерированного значения с уже записанными. использую функцию rand()%100. Вся проблема заключается в том, что уже на 9 строке матрицы 10х10 программа гоняет цикл по 10 минут из-за того что не может сгенерировать случайно число, которое не генерировала до этого. Все это из-за того что все же это псевдослучайные числа. Так вот как решить эту проблему, как быстро сгенерировать все 100 уникальных чисел?
Записать числа от 1 до 100 в одномерный массив по порядку.
Потом генерировать случайное число i от 0 до 99 (это будет номер элемента). И поменять местами нулевой елемент с i-тым елементом. Тоже самое для первого, второго и так до 99-го. Потом этот одномерный массив разложить по строкам.
А можно такой обмен делать сразу в матрице от 1 до 100. Только для обмена придется генерировать 2 индекса в диапазоне от 0 до 9
Артём Кобзарь
Артём Кобзарь
67 607
Лучший ответ
Сергей Баранов Такой алгоритм даёт неравномерное распределение вероятностей перестановок.
Один из вариантов:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
const int n = 10;
bool exists(int a[n * n], int v){
 if (a[v]){
  a[v] = 0;
  return false;
 } else
  return true;
}
int main(){
 srand(time(NULL));
 int a[n][n], b[n * n], v;
 for (int i = 0; i < n * n; b[i] = i + 1, ++i);
 for (int i = 0; i < n; cout << endl, ++i)
  for (int j = 0; j < n; a[i][j] = v + 1, printf("%4d", a[i][j]), ++j)
   for (v = rand() % 100; exists(b, v); v = rand() % 100);
 cin.get();
 return 0;
}
ИМ
Ирина Мисс
75 843
Заполняете массив последовательными числами от 1 до 100 и тасуете их, например, по алгоритму Фишера-Йетса:
https://ru.wikipedia org/wiki/Тасование_Фишера_—_Йетса
(заменить пробел на . )
Для простоты можно использовать и только один массив, переопределив для заполнения и тасования тот же массив, если он статический, как одномерный.
Простой и надёжный способ сделать Труъ-сгенерированный массив чисел от 1 до 100 - это сгенерировать 100 вещественных (float) чисел, скопировать этот массив, отсортировать скопированный, пронумеровать его элементы и посмотреть какому номеру какое число из сгенерированного массива соответствует. Способ Олега Олеговича также даёт качественный результат. А любые манипуляции с перестановками катастрофически снижают либо качество рандома, либо скорость.
Vassilii Fedorov
Vassilii Fedorov
31 768
Valera Valera Когда-то мне препод давал такой вариант
в двумерный массив [2][100] записываются данные
а в нулевую строку случайные числа, в первую последовательность необходимых 1..100 в данном случае, после чего массив сортируется по нулевой строке - в первой автоматически получаем случайную последовательность из нужных нам данных

PS: но я не вижу проблем с алгоритмом предложенным Александром П.
А если записать все числа в массив по порядку.
Вытаскивать их от туда через случайный индекс от 0 до длины массива.
После того, как число будет взято, удалять это число из массива и укорачивать массив на единицу.
Сергей Баранов > После того, как число будет взято, удалять это число из массива и укорачивать массив на единицу.
Не удивлюсь, если этот школьник будет удалять число, сдвигая весь массив после него на один элемент влево.
std::shuffle

Похожие вопросы