Существует несколько способов извлечения случайных чисел в диапазоне от случайных бит. Некоторые общие из них описаны в Специальная публикация NIST 800-90A, версия 1: Рекомендация для генерации случайных чисел с использованием детерминированных генераторов случайных битов
Хотя этот стандарт относится к детерминированным случайным битовым генерациям, существует полезное приложение под названием A.5 Преобразование случайных битов в случайное число, которое описывает три полезных метода.
Описанные методы:
Первые два из них не детерминированы, а генерируют число без каких-либо смещений. Они основаны на выборке отбраковки. Последний является постоянным по времени и детерминированным, но имеет ненулевое (незначительное) смещение. Это требует относительно большого количества дополнительной случайности для достижения пренебрежимого смещения.
Ваш алгоритм явно является версией метода Simple Discard, поэтому он прекрасен.
Конечно, вы должны использовать общий метод , который эффективен при любом значении N
. В этом случае метод комплексного отказа или простой модульный метод следует рассматривать по методу «Simple Discard». Существуют и другие, более сложные алгоритмы, которые еще более эффективны, но в целом вы можете использовать любой из этих двух.
Обратите внимание, что часто бывает полезно сначала проверить, является ли N
мощность из двух при генерации случайных значений в диапазоне [0, N)
. Если N
является степенью двух, тогда нет необходимости использовать какие-либо из этих, возможно, дорогостоящих вычислений; просто используйте нужные вам биты из генератора случайных бит или байтов.
Я надеюсь добавить еще один, более эффективный метод, основанный на выборке отбраковки в будущем.
Я использую C ++, но могу ответить на ваш вопрос. Алгоритм в порядке , но вы должны перефразировать ваш вопрос, чтобы отразить, что у вас возникли проблемы с пониманием алгоритма del>.
1) Почему мы создаем вложенный класс?
Чтобы избежать конфликта типов
+- IntersectionOfTwoSets (class) ------+
| | |
| o- Point (class) |
| | |
| o- intersectionOf (function) |
| |
+--------------------------------------+
можно реализовать без IntersectionOfTwoSets
, но обратите внимание, что [116 ] - очень распространенное имя, и, возможно, оно уже реализовано в любой библиотеке, которую вы собираетесь добавить в свой проект. реализация Point
в IntersectionOfTwoSets
делает вашу реализацию уникальной (концепция, известная как namespace
в C ++ и использование которой считается хорошей практикой программирования)
стандарт [1122 ] для цикла синтаксис:
blockquote>for
(init
;condition
;increment
])Заметьте, что отсутствует компонент приращения цикла, вместо этого вы найдете его в цикле
2) [ 1127] Как i ++ и j ++ реализованы в методе intersectionOf?
i++
- это простоi += 1
;- это упрощенная версия кода
given two sets a & b sort a & b initialize empty array (result) loop (...) | if (a[i] == b[j]) | add a[i] to result, then increment i & j | if (a[i] < b[j]) | increment i | if (b[j] < a[i]) | increment j | if (i >= a.size()) or (j >= b.size()) | stop return result
давайте проверим алгоритм на множестве целых чисел
let a: [2, 1, 10, 9] let b: [1, 5, 2, 7, 6] let result: [] Arrays.sort(a); // a: [1, 2, 9, 10] Arrays.sort(b); // b: [1, 2, 5, 6, 7] loop(...) | 1: add 1 to result, increment i & j | 2: add 2 to result, increment i & j | 3: (j == 2) increment only j (5 < 9) | 4: (j == 3) increment only j (6 < 9) | 5: (j == 4) increment only j (7 < 9) | 6: (j == 5) stop because j >= b.size() return result // [1, 2]
, он также должен работать на множестве точек
] 3) Как основной метод будет создавать объекты из двухточечного массива?
в C ++ синтаксис:IntersectionOfTwoSets::Point a[n], b[n]; or List<IntersectionOfTwoSets::Point> a, b;
, но в Java Я почти уверен, что это:
List<IntersectionOfTwoSets.Point> a, b; or IntersectionOfTwoSets::Point a = new IntersectionOfTwoSets::Point[n]; IntersectionOfTwoSets::Point b = new IntersectionOfTwoSets::Point[n];