Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实现卡片洗牌的逻辑_C++_Performance_Algorithm_Logic_Shuffle - Fatal编程技术网

C++ 实现卡片洗牌的逻辑

C++ 实现卡片洗牌的逻辑,c++,performance,algorithm,logic,shuffle,C++,Performance,Algorithm,Logic,Shuffle,我试图为一副牌实现一个类。“deck”包含的函数之一是shuffle void deck::shuffle() { int cardsleft = deck::cards; for(int i = 0; i < cardsleft ; i++) { srand(time(NULL)); int rdmn = rand() % cardsleft; card tempcard = deck::dcards[rdmn];

我试图为一副牌实现一个类。“deck”包含的函数之一是shuffle

void deck::shuffle()
{
    int cardsleft = deck::cards;
    for(int i = 0; i < cardsleft ; i++)
    {
        srand(time(NULL));
        int rdmn = rand() % cardsleft;
        card tempcard = deck::dcards[rdmn];
        deck::dcards[rdmn] = deck::dcards[i];
        deck::dcards[i] = tempcard;
    }
void-deck::shuffle()
{
int cardsleft=卡片组::卡片;
对于(int i=0;i
}

需要明确的是,deck::cards是一个整数,它计算了这个deck中剩余的卡数,deck::dcards是这个deck中的一个卡数组

我的问题是:这不会产生很好的结果。是不是我需要通过指针来传递引用?如果是,是如何做到的

或者,这可能只是糟糕的算法吗?也许我只是需要一个更好的洗牌逻辑。请告诉我。注意:是的,我知道在“algorithm.h”库中有一个std::shuffle std::random_shuffle函数,但是这些函数只适用于向量,而不是我在这里使用的数组,不是吗

更新:nvm,我刚刚意识到我的问题可以在这里得到回答:

因此,这是一个逻辑缺陷,而不是我的实现。

当您这样做时

srand(time(NULL));
将种子设置为当前时间。由于此循环将在1秒内运行(时间函数的正常分辨率),因此种子将在循环中重置为相同的起始值,使您几乎每次都获得相同的随机数

您应该只为随机数生成器设定一次种子,最好在
main
函数中尽早设定


您可能还想在查看时查看。

srand(time(NULL));
将种子设置为当前时间。由于此循环将在1秒内运行(时间函数的正常分辨率),因此种子将在循环中重置为相同的起始值,使您几乎每次都获得相同的随机数

您应该只为随机数生成器设定一次种子,最好在
main
函数中尽早设定



你也可以检查.< /p>< P>如果你需要洗牌,你应该考虑<代码> STD::RealthyStuffle (或者<代码> STD::在C++ 11中改组< /COD>)。它按顺序重新排列元素,使这些元素的每个可能排列具有相同的出现概率。是的,它可以用于数组,而不仅仅是向量。任何属于“范围”的东西


现在回到您的代码,您的种子设定有问题。生成(伪)随机数的算法采用初始值,即种子。给予相同的种子,它们产生相同的数字序列。这意味着您只需对生成的随机数进行一次种子设定(每个线程),否则您将一次又一次地生成相同的数字序列。在这个循环中,你得到一个相同的数字,直到时间改变一个新的种子值。

< P>如果你需要洗牌,你应该考虑<代码> STD::RouthSuffle改组< /C> >(或者<代码> STD::Scffle C++ 11)。它按顺序重新排列元素,使这些元素的每个可能排列具有相同的出现概率。是的,它可以用于数组,而不仅仅是向量。任何属于“范围”的东西


现在回到您的代码,您的种子设定有问题。生成(伪)随机数的算法采用初始值,即种子。给予相同的种子,它们产生相同的数字序列。这意味着您只需对生成的随机数进行一次种子设定(每个线程),否则您将一次又一次地生成相同的数字序列。在你的这个循环中,你会在一段时间内得到相同的数字,直到时间改变为止,一个新的种子值被使用。

std::random\u shuffle
std::shuffle
使用任何随机访问范围。数组是一个随机访问范围。
std::random_shuffle
std::shuffle
可用于任何随机访问范围。数组是一个随机访问范围。“只需为随机数生成[或]一次种子(每个线程)”。根据cppreference.com,不保证是线程安全的,它的实现定义了
rand()
本身是否是线程安全的。如果实现使用特定于线程的数据,那么您的建议可能是好的;如果它处于锁定状态,那么从多个线程调用
srand()
将破坏周期性保证。无论如何-主要的一点是需要参考实现文档。“只需为随机数生成[或]种子一次(每个线程)”。根据cppreference.com,不保证是线程安全的,它的实现定义了
rand()
本身是否是线程安全的。如果实现使用特定于线程的数据,那么您的建议可能是好的;如果它处于锁定状态,那么从多个线程调用
srand()
将破坏周期性保证。无论如何-主要的一点是需要参考实现文档。