Случайное число C++ из набора
Вопрос
Можно ли на C++ напечатать случайное число из набора чисел с помощью ОДНОГО ОДНОГО оператора?
Допустим, набор равен {2, 5, 22, 55, 332}.
Я поискал rand(), но сомневаюсь, что это возможно сделать в одном операторе.
Решение
Допустим, эти числа находятся в наборе размером 5, все, что вам нужно сделать, это найти случайное значение, умноженное на 5 (чтобы сделать его равновероятным).Предположим, что метод rand() возвращает случайное значение в диапазоне от 0 до 1.Умножьте это число на 5 и приведите его к целому числу, и вы получите равновероятные значения от 0 до 4.Используйте это для извлечения из индекса.
Я не знаю синтаксиса C++.Но вот как это должно выглядеть
my_rand_val = my_set[(int)(rand()*arr_size)]
Здесь я предполагаю, что rand() — это метод, который возвращает значение от 0 до 1.
Другие советы
int numbers[] = { 2, 5, 22, 55, 332 };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
Бессмысленное объединение всего в одно выражение — это практически то, чем был тернарный оператор. изобретенный for (у меня нет никаких трюков с составными операторами, как в Литбе):
std::cout << ((rand()%5==0) ? 2 :
(rand()%4==0) ? 5 :
(rand()%3==0) ? 22 :
(rand()%2==0) ? 55 :
332
) << std::endl;
Пожалуйста, не нападайте на меня перед моим рецензентом кода.
А, вот и правильное равномерное распределение (при условии, что rand()
является однородным в своем диапазоне) в том, что можно было бы назвать «единственным утверждением» с натяжкой.
Это оператор итерации, но также и цикл for с большим блоком, содержащим несколько операторов.Синтаксис не различает.На самом деле это содержит два утверждения:все это является утверждением, и все это, за исключением for(...)
часть является заявлением.Так что, вероятно, «один оператор» означает один оператор-выражение, а это не так.Но в любом случае:
// weasel #1: #define for brevity. If that's against the rules,
// it can be copy and pasted 7 times below.
#define CHUNK ((((unsigned int)RAND_MAX) + 1) / 5)
// weasel #2: for loop lets me define and use a variable in C++ (not C89)
for (unsigned int n = 5*CHUNK; n >= 5*CHUNK;)
// weasel #3: sequence point in the ternary operator
((n = rand()) < CHUNK) ? std::cout << 2 << "\n" :
(n < 2*CHUNK) ? std::cout << 5 << "\n" :
(n < 3*CHUNK) ? std::cout << 22 << "\n" :
(n < 4*CHUNK) ? std::cout << 55 << "\n" :
(n < 5*CHUNK) ? std::cout << 332 << "\n" :
(void)0;
// weasel #4: retry if we get one of the few biggest values
// that stop us distributing values evenly between 5 options.
Если это будет единственный код во всей программе, и вы не хотите, чтобы он каждый раз возвращал одно и то же значение, вам нужно вызвать srand()
.К счастью, это можно встроить.Измените первую строку на:
for (unsigned int n = (srand((time(0) % UINT_MAX)), 5*CHUNK); n >= 5*CHUNK;)
Давайте больше никогда не будем говорить об этом дне.
Да, это возможно.Не очень интуитивно понятно, но вы об этом просили:
#include <time.h>
#include <stdlib.h>
#include <iostream>
int main()
{
srand(time(0));
int randomNumber = ((int[]) {2, 5, 22, 55, 332})[rand() % 5];
std::cout << randomNumber << std::endl;
return 0;
}
Ваши критерии «единого утверждения» очень расплывчаты.Вы имеете в виду одну машинную инструкцию, один вызов stdlib?
Если вы имеете в виду одну машинную инструкцию, ответ — нет, без специального оборудования.
Если вы имеете в виду один вызов функции, то конечно можно.Вы можете написать простую функцию, которая будет делать то, что вы хотите:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int setSize = 5;
int set[] = {2, 5, 22, 55, 332 };
srand( time(0) );
int number = rand() % setSize;
printf("%d %d", number, set[number]);
return 0;
}