Доска Бинго: Генерация уникальных ценностей - PullRequest
0 голосов
/ 24 сентября 2011

У меня проблемы с генерацией уникальных значений, которые НЕ повторяются для этой доски бинго. Мой код относительно прост: я использую вложенный цикл 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);
}

Ответы [ 3 ]

2 голосов
/ 24 сентября 2011

Попробуйте заполнить std::vector номерами-кандидатами, затем выполните std::random_shuffle и возьмите первое N.

1 голос
/ 28 августа 2012

Это какой-то код, который я придумал для своего маленького проекта

Ничего особенного, но он генерирует уникальные числа и для меня это удовлетворяет потребность.

1 голос
/ 24 сентября 2011

Обычный подход, который я использую для этого «генерирования 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();
    }
}
...