【问题标题】:Bingo Board: Generating unique values宾果板:产生独特的价值
【发布时间】:2011-11-24 08:55:46
【问题描述】:

我无法为这个宾果板生成不会重复的唯一值。我的代码比较简单:我使用嵌套的 for 循环来生成带有一些打印语句的值;在每次嵌套迭代时,我都会检查生成的值是否存在于数组中。如果存在,则返回true,并且生成的值选择一个新的随机数。我认为通过在每次迭代时启动 srand() 并使用循环中的计数作为其种子,我将能够实现这一点。不幸的是,这似乎不太可能。

这是如何实现的?

我的代码:

#define MAX 100
#define MIN 1

using std::vector;

bool Board::checkValues(unsigned int array[], unsigned int valueToCheck)
{
    int len = sizeof(array) / sizeof(int);

    bool numberExists = false;

    static int repeatCount = 0;

    for(int i = 1; i < len; i++)
    {
        if (valueToCheck == array[i])
        {
            numberExists = true;
            repeatCount++;
            break;
        }
    }

    return numberExists;
}

Board::Board(unsigned int numberOfRows, unsigned int numberOfColumns)
{
    this->numRows = numberOfRows;
    this->numColumns = numberOfColumns;

    for (int i = 0; i < this->numRows; i++)
    {
        this->board.push_back(vector<unsigned int>(this->numColumns, 0));
    }

    this->valuesVisited[numberOfRows * numberOfColumns];
}

void Board::generate()
{
    int repeatCount = 0;

    for(int i = 0; i < this->numRows; i++)
    {
        bool atMid = false;

        if (i == this->numRows / 2 - 1)
        {
            atMid = true;
        }

        for(int j = 0; j < this->numColumns; j++)
        {
            if (atMid && j == this->numColumns / 2 - 1)
            {
                printf(" Free ");
                continue;
            }

            int seed = (i + 1) * (j + 1);

            unsigned int randNumber = generateRand(MIN, MAX, seed);

            bool numberExists = checkValues(this->valuesVisited, randNumber);

            if (numberExists)
            {
                //int equation = (randNumber % 10) + (i * j) / (randNumber + randNumber);

                randNumber = generateRand(MIN, MAX, seed) - (i * j);
                repeatCount++;
            }

            this->valuesVisited[(i + 1) * (j + 1)] = randNumber;

            this->board[i][j] = randNumber;

            printf(" %d ", board[i][j]);
        }

        std::cout << "\n\n";
    }

    printf("You have %d repeats", repeatCount);
}

【问题讨论】:

  • 您在寻找没有重复的随机生成器吗?为什么不做一个赎金排列,然后迭代地选择元素呢?

标签: c++ random unique srand


【解决方案1】:

考虑用候选编号填充std::vector,然后对其执行std::random_shuffle 并取第一个N。

【讨论】:

    【解决方案2】:

    我用于“生成 n 个唯一随机数”的常用方法是用数字的总范围(对你来说,这里是 MIN -> MAX)填充一个向量,random_shuffle() 然后拉出尽可能多的值正如我从前面需要的那样。如果性能非常关键,我认为可能有稍微更有效的方法,但它似乎在我目前需要的所有情况下都做得很好。

    有点像

    std::vector<int> numbers;
    int index = MIN;
    std::generate_n(back_inserter(numbers), MAX - MIN + 1,
        [&](){return index++;});
    
    std::random_shuffle(numbers.begin(), numbers.end());
    
    for(int i = 0; i < this->numRows; i++)
    {
        for(int j = 0; j < this->numColumns; j++)
        {
            this->board[i][j] = numbers.back();
            numbers.pop_back();
        }
    }
    

    【讨论】:

    • 好吧,如果您担心效率问题,您始终可以完全避免从vector 弹出值,而是将索引或迭代器保留到下一个数字。
    • +1 用于使用std::random_shuffle。 (我建议你在它前面加上std::,因为它表明random_shuffle来自哪里)。
    • 我不太了解这一点,这里:generate_n(back_inserter(numbers), MAX - MIN + 1, [&](){return index++;});您介意向我解释一下返回值(在参数中???)的工作原理吗?
    • @Holland:[&amp;](){return index++;} 是一个 C++11 lambda,lambda 函数是参数。
    • @Holland:这是一个新的 C++11 lambda。它基本上是一个小功能。在这种情况下,它所做的只是在每次调用时返回下一个计数。整个生成语句相当于for (int num = MIN; num &lt;= MAX; ++num) numbers.push_back(num);
    【解决方案3】:

    这是我为我的小项目编写的一些代码

    没什么花哨的,但它会生成唯一的数字,对我来说它满足了需求。

    for (int a = 0; a <= 89; a++) //populate the array with numbers 1-90
    {
        bNumbers[a].Number = a + 1;
    }
    for (int a = 0; a < bNumbers.Length; a++) //swap positions of the generated numbers
    {
        int rBingo = bMain.rndNum.Next(a, bNumbers.Length); //generate random number
        // swap numbers round in the array
        int tmpNum = bNumbers.Number;
        bNumbers.Number = bNumbers[rBingo].Number;
        bNumbers[rBingo].Number = tmpNum;
        //end of swap                 
    }     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多