Бессмысленное превращение вещей в одно выражение - это практически то, для чего был изобретен троичный оператор (у меня нет ни одной хитрости составного оператора litb):
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;)
Теперь, давайте никогда больше не будем говорить об этом дне.