【问题标题】:Non-repeating random number generator非重复随机数发生器
【发布时间】:2011-07-19 21:59:57
【问题描述】:

我想制作一个不会重复给出的数字的数字生成器 已经(C++)。

我只知道:

int randomgenerator(){
  int random;
  srand(time(0));
  random = rand()%11;
  return(random);
} // Added this on edition

那个函数给了我多余的数字。

我正在尝试创建一个问卷调查程序,以随机顺序给出 10 个问题,我不希望任何问题再次出现。

有人知道语法吗?

【问题讨论】:

  • 如果你的随机数生成器不能重复,它就失去了随机性的一个重要方面。如果有人知道时间段,他们的猜测准确度会随着时间段接近尾声而提高,最后一次猜测的确定性为 100%。
  • srand() 应该运行 ONCE 并且只在程序启动时运行一次。
  • 你可以简单地将最后一个值存储为 int,如果新值等于最后一个值,则在 1 和你想要的最大值减去你得到的数字之间添加一个随机数。你可以简单地使用模数来做到这一点,它比简单地使用 rand() 更随机 :)
  • @corsiKa 好吧,C++ 和 C 中的伪随机生成器很烂。
  • @AnonymousPi 无论您认为“C 和 C++”中的 RNG 有多糟糕,尝试制作自己的 RNG 肯定会更糟。 -gguuaarraanntteeeedd

标签: c++ random generator


【解决方案1】:

我会做什么:

  • 生成一个长度为 N 的向量并用值 1,2,...N 填充它。
  • 使用std::random_shuffle
  • 如果您有 30 个元素但只需要 10 个,请使用向量中的前 10 个。

编辑:我不知道问题是如何存储的,所以.. :)

我假设问题被存储在一个随机访问的向量或类似的东西中。现在我生成了 10 个不重复的随机数:7、4、12、17、1、13、9、2、3、10。

我会将它们用作问题向量的索引:

std::vector<std::string> questions;
//fill with questions
for(int i = 0; i < number_of_questions; i++)
{
    send_question_and_get_answer(questions[i]);
}

【讨论】:

  • 我喜欢这个,但我仍然不知道它将如何帮助我回答问题。
  • @Jpeh 从您的示例中,看起来您想要一个生成器来返回一个数字,然后您将使用该数字作为问题列表的索引。此处提出的答案允许您获取问题列表,随机排列其顺序,然后遍历它。
  • 在 C++11 中,您可以使用 std::iota 来填充向量。
【解决方案2】:

您正试图以“错误的方式”解决问题。

试试这个(假设你有一个带有问题 ID 的 vector&lt;int&gt;,但同样的想法适用于你所拥有的任何东西):

  1. 获取从 0 到 N-1 的随机 R,其中 N 是容器中的问题数
  2. 将问题 R 添加到另一个“选定”问题集合中
  3. 如果“选定的问题”集合有足够的项目,那么您就完成了
  4. 从您的原始容器中删除问题 R(现在 N 减少了 1)
  5. 转到 1

【讨论】:

  • 嗨,你能帮我创建实际的函数吗?我是 C++ 新手,我不知道向量是什么。 D:
  • @Jpeh:那么您的问题是如何存储的?还有,这是作业吗?
  • 我正在使用我在问题中编写的函数来选择 0-10 之间的随机数,并将该值返回到我的主程序。无论哪个值等于某个问题(例如,如果随机 == 1,那么我将调用该函数:“问题 1”。不,这不是家庭作业。我只是这里的编程爱好者。:D跨度>
  • @Jpeh:Max Lybbert 的回答有一些您可以使用的示例代码。但是您还需要阅读一些向您介绍 STL 的书。
【解决方案3】:

听起来您实际上想shuffle a deck of cards(在这种情况下,“卡片”是问题或问题编号)。

在 C++ 中,我会这样做:

#include <vector>
#include <algorithms>

std::vector<int> question_numbers;
for (unsigned int i = 0; i < 10; ++i)
    question_numbers.push_back(i+1);
std::random_shuffle(question_numbers.begin(), question_numbers.end());

// now dole out the questions based on the shuffled numbers

您不必分发所有问题,就像每次玩游戏时都必须分发一副牌一样。当然可以,但没有这样的要求。

【讨论】:

    【解决方案4】:

    创建一个包含 10 个元素(数字 1-10)的向量,然后使用 std::random_shuffle 对其进行随机播放。然后遍历它。

    【讨论】:

    • @Benjamin:我认为OP想要的是从M中随机选择N。
    • @Jon:是吗?所以你只需要遍历 N 个元素。
    • @Jon:本质上是一样的,但是这种方法给你 O(N+M) 时间,而你给 O(NM)。
    • @Benjamin:显然。我想说的是,“创建一个由 10 个元素组成的向量 (数字 1-10)”的措辞如果不是不正确的话是具有误导性的,因为向量应该是 0...M-1。我会给出 +1,因为如果答案是为解决 OP 的问题而写的,那么这在算法上是更好的。
    • 我不确定我是否理解你@Jon,特别是因为你给共产鸭 +1 并且他推荐了完全相同的东西。
    【解决方案5】:

    应该看起来更像这样:(注意:不能解决你原来的问题)。

    int randomgenerator(){
      int random;
    
      // I know this looks re-dunand compared to %11
      // But the bottom bits of rand() are less random than the top
      // bits do you get a better distribution like this.
    
      random = rand() / (RAND_MAX / 11);
    
      return random;
    }
    
    int main()
    {
        // srand() goes here.
        srand(time(0));
    
        while(true)
        {
            std::cout << randomgenerator() << "\n";
        }
    }
    

    解决原始问题的更好方法是预先生成数字,这样您就知道每个数字只会出现一次。然后随机打乱顺序。

    int main()
    {
        int data[] =  { 0,1,2,3,4,5,6,7,8,9,10,11};
        int size   =  sizeof(data)/sizeof(data[0]);
    
        std::random_shuffle(data, data + size);
    
        for(int loop = 0; loop < size; ++loop)
        {
            std::cout << data[loop] << "\n";
        }
    }
    

    【讨论】:

      【解决方案6】:

      为什么不使用一些 STL 来为您执行检查?想法:

      创建一个(最初为空)集合,包含 10 个整数,作为随机问题的索引(它们将是不同的,因为集合禁止重复项目)。继续在 [0, num_of_questions-1] 中推送随机数,直到它增长到 10 的大小(重复将被自动拒绝)。当您准备好该集合后,对其进行迭代并输出相应索引的问题:

      std::vector<std::string> questions = /* I am assuming questions are stored in here */
      std::set<int> random_indexes;
      
      /* loop here until you get 10 distinct integers */
      while (random_indexes.size() < 10) random_indexes.insert(rand() % questions.size());
      
      for (auto index: random_indexes){
          std::cout << questions[index] <<std::endl;
      }
      

      我可能遗漏了一些东西,但在我看来,使用随机问题或索引的答案会执行更多计算或使用不必要的内存开销。

      【讨论】:

        【解决方案7】:
        //non repeating random number generator
        for (int derepeater = 0; derepeater < arraySize; derepeater++)
        {
            for (int j = 0; j < arraySize; j++)
            {
                for (int i = arraySize; i > 0; i--)
                {
                    if (Compare[j] == Compare[i] && j != i)
                    {
                        Compare[j] = rand() % upperlimit + 1;
                    }
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2011-11-24
          • 1970-01-01
          • 2014-06-10
          • 1970-01-01
          • 1970-01-01
          • 2013-04-06
          相关资源
          最近更新 更多