2011-09-24 90 views
0

我無法生成唯一不會爲此賓果遊戲主板重複的值。我的代碼相對簡單:我使用嵌套for循環來生成一些打印語句的值;在每次嵌套迭代時,我會檢查數組中是否存在生成的值。如果存在,則返回true,並且生成的值將選擇一個新的隨機數。我認爲通過在每次迭代時啓動srand(),並使用循環中的count作爲它的種子,我將能夠實現這一點。不幸的是,這似乎不太可能。賓果遊戲板:生成唯一值

這是如何實現的呢?

我的代碼:

#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); 
} 
+0

你在找一個沒有重複的隨機生成器嗎?爲什麼不只是做一個贖金置換,然後迭代地選擇元素? – amit

回答

2

考慮填補與候選人數的std::vector,然後執行就可以了std::random_shuffle,並採取第一N.

1

通常的方法我用這個「產生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(); 
    } 
} 
+0

那麼,如果你有效率問題,你總是可以避免從'vector'中彈出數值,並且保持索引或迭代器到下一個數字。 –

+0

+1使用'std :: random_shuffle'。 (我建議你用'std ::'作爲前綴,因爲它表示'random_shuffle'來自哪裏]。 – Nawaz

+0

我不是很追隨這個位,在這裏:generate_n(back_inserter(numbers),MAX - MIN + 1, [&](){return index ++;}); 你介意給我解釋返回值(在一個參數???中)的工作原理嗎? – zeboidlund

1

這是一些代碼,我想出了我的小項目

沒有什麼幻想,但它產生的唯一號碼,對我來說滿足了需求。

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     
}