循环中奇怪的srand行为; C ++

时间:2012-07-18 15:00:31

标签: c++ srand

只是编写一个程序来洗牌一副牌,并根据RNG是在for循环的内部还是外部播种而得到不同的行为; 即

  for(int i = 0; i < 52; i++)
{
  srand(time(0));  
  Card temp = deck[i];
  int toSwap = rand()%52;
  deck[i] = deck[toSwap];
  deck[toSwap] = temp;
}

给出输出

Nine of Hearts
Ace of Clubs
Two of Clubs
Three of Clubs
Four of Clubs

等,但

void DeckOfCards::shuffle()
{
  srand(time(0));  
  for(int i = 0; i < 52; i++)
  {
  Card temp = deck[i];
  int toSwap = rand()%52;
  deck[i] = deck[toSwap];
  deck[toSwap] = temp;
  }
  currentCard =0;
}

导致

Ace of Hearts
Queen of Spades
Four of Hearts
Seven of Clubs
Five of Hearts

(正确的功能)。任何人都知道为什么重新种植RNG会导致这种情况吗?

4 个答案:

答案 0 :(得分:3)

如果你需要伪随机数,只需要一次种子。如果您多次调用srand并且如果在时钟种子更改之前执行此操作,那么您将获得相同的值而不是随机的。刚刚开始种子一次。您可以打开其他程序(winamp等..)以获得更多随机值(您需要减慢程序;)或者为随机迭代制作空循环可以修复第一个程序。但你需要非常大的随机数,如20亿(必须小于40亿))

答案 1 :(得分:3)

由于时间(NULL)仅每秒更改一次,因此如果for循环完成时间不超过一秒,则RNG种子将相同。

答案 2 :(得分:0)

虽然其他人完全正确,你不想在循环中使用srand(time(0)),因为你会得到较差的随机性,因为你重复设置相同的种子,你可能希望保持这是为了调试:如果您需要能够“重播”一个案例,请将种子写入日志文件并允许显式设置种子。否则,使用随机数调试应用程序可能相当棘手......

答案 3 :(得分:0)

你可以使用boost posix时间。

但是在所有情况下如果你只需要调用srand两次,你可以使用两个不同的固定值。

或者我使用此功能以毫秒为单位获得时间

 inline long
    getTimeMs ()
    {
      struct timeval start;
      long mtime;

      gettimeofday (&start, NULL);

      mtime = ((start.tv_sec) * 1000 + start.tv_usec / 1000.0) + 0.5;

      return mtime;
    }

问候