C ++ случайное число из набора - PullRequest
4 голосов
/ 14 марта 2010

Можно ли напечатать случайное число в C ++ из набора чисел с помощью оператора ONE SINGLE?

Допустим, набор равен {2, 5, 22, 55, 332}

Я посмотрел на rand (), но сомневаюсь, что это можно сделать в одном выражении.

Ответы [ 5 ]

11 голосов
/ 14 марта 2010
int numbers[] = { 2, 5, 22, 55, 332 };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
5 голосов
/ 14 марта 2010

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

Теперь, давайте никогда больше не будем говорить об этом дне.

2 голосов
/ 14 марта 2010

Скажем, эти числа в наборе размера 5, все, что вам нужно сделать, это найти случайное значение, умноженное на 5 (чтобы оно было равным). Предположим, что метод rand () возвращает вам случайное значение в диапазоне от 0 до 1. Умножьте его на 5 и приведите к целому числу, вы получите равновероятные значения в диапазоне от 0 до 4. Используйте это для выборки из индекса.

Я не знаю синтаксис в C ++. Но так это должно выглядеть

my_rand_val = my_set[(int)(rand()*arr_size)]

Здесь я предполагаю, что rand () - это метод, который возвращает значение от 0 до 1.

0 голосов
/ 14 марта 2010

Ваши критерии "одного высказывания" очень расплывчаты. Вы имеете в виду одну машинную инструкцию, один вызов 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;
}
0 голосов
/ 14 марта 2010

Да, это возможно. Не очень интуитивно понятно, но вы просили об этом:

#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;
}    
...