Есть много способов сделать это, и выбор зависит от того, каковы основные требования.
// brute force (assumes that n < m):
int res = rand() % (k - 2) + 1;
if (n <= res) ++res;
if (m <= res) ++res;
// elimination:
int res = rand() % k + 1;
while (res == n || res == m)
res = rand() % k;
// table lookup:
int results[] = { 1, 2, 3, 5, 6, 8 }; // n == 4, m == 7
int res = rand() % (sizeof results / sizeof *results);
res = results[res];
Я бы, вероятно, go с подходом грубой силы; это всегда работает, если вы знаете относительный порядок n
и m
. Более сложная версия будет проверять, какая из них меньше, и при необходимости поменять их местами так, чтобы n
было меньше m
.
. Исключение также всегда корректно, а когда k
велико, l oop будет выполняться редко, поэтому может быть немного быстрее, чем грубая сила. Когда k
мало, оно может l oop много раз. Этот подход иногда используется при создании более сложных распределений, таких как пара координат, которые находятся внутри круга (сгенерируйте две координаты и, если они находятся вне круга, отбросьте их и попробуйте снова).
Поиск в таблице вероятно, это не лучший выбор, но если вы знаете значения k
, n
и m
во время компиляции, он может быть немного быстрее, чем любой из двух других. Конечно, при больших значениях k
много пустого места.