【问题标题】:C++ random number from a set集合中的 C++ 随机数
【发布时间】:2011-01-27 10:48:39
【问题描述】:

是否可以在 C++ 中使用 ONE SINGLE 语句从一组数字中打印一个随机数?

假设集合是 {2, 5, 22, 55, 332}

我查找了 rand(),但我怀疑是否可以在单个语句中完成。

【问题讨论】:

  • 您的问题不准确。例如,我可以做到:cout << (rand()%5); 确实从一组 5 个数字中用一个语句打印一个随机数。集合是如何给出的,它是如何给出的?数量是如何限制的? (例如,它们必须能够表示至少达到 INT_MAX 的值吗?)。另外,请注意复合语句是单个语句。 这是一个测验吗!?
  • 谁在乎你是否可以在一份声明中做到这一点?告诉我们为什么它很重要。

标签: c++ random srand


【解决方案1】:

假设这些数字的大小为 5,您所要做的就是找到一个随机值乘以 5(使其等概率)。假设 rand() 方法返回一个介于 0 到 1 之间的随机值。将其乘以 5 并将其转换为整数,您将得到 0 到 4 之间的等概率值。使用它从索引中获取。

我不知道 C++ 的语法。但这就是它应该的样子

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

这里我假设 rand() 是一个返回 0 到 1 之间值的方法。

【讨论】:

    【解决方案2】:
    int numbers[] = { 2, 5, 22, 55, 332 };
    int length = sizeof(numbers) / sizeof(int);
    int randomNumber = numbers[rand() % length];
    

    【讨论】:

      【解决方案3】:

      是的,这是可能的。不是很直观,但你要求它:

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

      【讨论】:

      • 不过,仅作为 GCC 扩展。使用-pedantic:“警告:ISO C++ 禁止复合文字”
      【解决方案4】:

      您的“单一陈述”标准非常模糊。你的意思是一个机器指令,一个 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;
      }
      

      【讨论】:

        【解决方案5】:

        将事物毫无意义地变成一个表达式实际上是 发明了三元运算符的目的(我没有任何 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;)
        

        现在,让我们再也不要谈论这一天了。

        【讨论】:

        • rand() 的多次调用是否保持每个选项的概率相同?我的概率计算不是很好:)
        • 如果你忽略了如果 5 引入的微小偏差!不均分 RAND_MAX,每个数字的概率相同。好的!我必须记住这一点......(但我保证不会透露我是从谁那里学到的。:-)
        • 看起来很像(假设 rand() % N 的结果很好 - 根据需要替换为更好的生成器)。 1 / 5 有机会获得 2 个。(4 / 5) * (1 / 4) = 1 / 5 有机会获得 5 个等。
        • 是的,我的评估与 UncleBens 完全相同。如果我们暂时假设rand()%N 是 N = 2 .. 5 的均匀分布离散随机变量,那么它不会影响概率。因为不是这样,你从我的表达中得到的偏见与你从只做一个 rand()%5 的表达中得到的偏见略有不同。但是还没有人费心提供一个基于 2^N 值的适当均匀分布的 5 值 RNG。它比问题的其余部分加起来更大,并且需要一个循环,所以我认为在单个表达式中是不可行的。
        猜你喜欢
        • 1970-01-01
        • 2011-11-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-16
        • 1970-01-01
        • 2023-01-24
        • 2023-01-19
        • 2015-12-20
        相关资源
        最近更新 更多