数组,避免拉取 Duplicates,简单代码,C++

Posted

技术标签:

【中文标题】数组,避免拉取 Duplicates,简单代码,C++【英文标题】:Array, avoid pulling Duplicates, simple code, C++ 【发布时间】:2021-12-25 20:22:13 【问题描述】:

这是一个纸牌游戏,我在两个函数的帮助下从牌组(数组)中抽取 2 张牌。

数组的每个元素代表一张牌,其符号为黑桃、红心、方块或梅花。

数组中的这些数字 \5 \4 \3 \6,分别代表梅花、Dimaond、Hearts、黑桃(如果你好奇的话)

问题!

当我抽两次牌时,有时会得到重复。同一张牌两次。

如何确保同一张牌不会被抽两次? 如何避免重复?

这就是代码的样子。

关于数组的一些信息... 在数组中越远,元素的值就越高。 我已经缩短了数组...以便于测试解决方案...稍后数组将是 52 个元素。

array<string, 3> cards =  "Ess \5", "Ess \4", "Ess \3" ;


//The function.
pair<string, int> draw_card()

    int random_index = rand() % 52;
    string card = cards[random_index];
    return  card, random_index ;


int main()

// Seed, random.
 srand((unsigned int)time(NULL));



// Calling the function 2 times.
    pair<string, int> you_drew = draw_card();
    cout << "You drew: " << you_drew.first << endl;

    pair<string, int> comp_drew = draw_card();
    cout << "Computer drew: " << comp_drew.first << endl;



// Deciding the winner.
    int your_score 0 ;
    int the_computers_score 0 ;

    if (you_drew.second > comp_drew.second) 
        cout << "You Won!" << endl;
        your_score++;
    
    else if (you_drew.second < comp_drew.second) 
        cout << "You Lost!" << endl;
        the_computers_score++;
    

        return 0;
   

一切正常,除了有时我得到重复......我想确保我不能得到那个...... 不知何故,当我画一张卡片时,数组中的元素不应该被画出来。我想避免重复。请帮帮我!

这样的工作不应该吗?不是但..不应该吗?

pair<string, int> comp_drew = draw_card();

        if (you_drew == comp_drew) 
            bool run8 = true;
            while (run8) 
                pair<string, int> comp_drew = draw_card();


                if (comp_drew != you_drew) 
                     cout << "Computer drew: " << comp_drew.first << endl;
                    run8 = false;
                
            

        

或者也许是另一种解决方案.. 也许在调用一次函数后,我可以从数组中删除返回索引?

【问题讨论】:

一些一般性的想法。您可以将 array 更改为 vector 并在绘制后擦除每个元素。还可以看看std::shuffle,它可以用来在你洗牌后迭代vector 感谢您的帮助。我正在学习编程,任务是使用数组。我会看看 shuffle。还有其他想法吗? 【参考方案1】:

你可以将抽到的牌交换到最后,下次只选择小于51的索引。

int array_len = 52; // global variables are not great, but it's easier here
pair<string, int> draw_card()

    int random_index = rand() % array_len;
    --array_len;
    string card = cards[random_index];
    std::swap(cards[random_index], cards[array_len]);
    
    return  card, random_index ;

【讨论】:

谢谢 n314159。现在我没有得到重复的值。但是比较,决定获胜者现在不起作用......现在有时我的代码结尾(决定获胜者)不能决定获胜者......它是空白的...... 我回答了我自己的问题以强调此解决方案的问题。 @user904963 由于我们不想再使用最后一张卡片,因此数组的长度会隐式更改。第一次和第二次调用这个方法是有区别的。 @gunnar20008 我错过了您使用索引来比较两张卡。当您连续两次获得相同的随机数时,这将中断。这是唯一可能发生的方式。在您的情况下,您可以将相等情况添加到“您丢失”分支。因为如果你两次得到相同的数字,第二次你将抽到最初最高的牌。如果您尝试多次调用该事物,这将中断。【参考方案2】:

有很多不同的方法可以做到这一点。

std::random_shuffle

#include <iostream>
#include <algorithm>

using namespace std;

class CardMachine 
    static unsigned constexpr DECK_SIZE = 4;
    int cards[DECK_SIZE] = 1,2,3,4;
    int lastUsedCardIndex = -1;
public:
    int getCard() 
        if (lastUsedCardIndex == DECK_SIZE - 1)
            shuffle();
        return cards[++lastUsedCardIndex];
    
    
    void shuffle() 
        random_shuffle(begin(cards), end(cards));
    
;

int main()

    CardMachine cardMachine = CardMachine();
    
    cout << "unhsuffled - 1,2,3,4 without duplicates:" << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    
    cout << "Shuffled. Random order, and still no duplicates:" << endl;
    cardMachine.shuffle(); // or call getCard which can shuffle
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;

    return EXIT_SUCCESS;

将卡片标记为已使用

#include <iostream>
#include <random>

using namespace std;

class CardMachine 
    static unsigned constexpr DECK_SIZE = 4;
    inline static int constexpr cards[DECK_SIZE] = 1,2,3,4;
    bool cardIsGone[DECK_SIZE] = false, false, false, false;
public:
    int getCard() 
        while(true) 
            int const RANDOM_INDEX = rand()%DECK_SIZE;
            if(!cardIsGone[RANDOM_INDEX]) 
                cardIsGone[RANDOM_INDEX] = true;
                return cards[RANDOM_INDEX];
            
        
    
    
    void shuffle() 
        for(bool &isGone : cardIsGone)
            isGone = false;
        lastUsedCardIndex = -1;
    
;

int main()

    CardMachine cardMachine = CardMachine();
    
    cout << "Shuffled - Random order, and still no duplicates:" << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    
    cout << "Shuffled. Random order, and still no duplicates:" << endl;
    cardMachine.shuffle(); // Causes infinite loop if you call getCard DECK_SIZE + 1 times
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;

    return EXIT_SUCCESS;

这不是最有效的解决方案,但对于像 52 这样的小值,它应该是即时的。

将用过的牌交换到后面并跟踪范围

#include <iostream>
#include <random>

using namespace std;

class CardMachine 
    static unsigned constexpr DECK_SIZE = 4;
    int cards[DECK_SIZE] = 1,2,3,4;
    int lastCardIndexExlusive = DECK_SIZE;
public:
    int getCard() 
        int const RANDOM_INDEX = rand()%lastCardIndexExlusive;
        swap(cards[RANDOM_INDEX],cards[lastCardIndexExlusive - 1]);
        return cards[--lastCardIndexExlusive];
    
    
    void shuffle() 
        lastCardIndexExlusive = DECK_SIZE;
    
;

int main()

    CardMachine cardMachine = CardMachine();
    
    cout << "Shuffled - Random order, and still no duplicates:" << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    
    cout << "Shuffled. Random order, and still no duplicates:" << endl;
    cardMachine.shuffle(); // Causes exception if getCard DECK_SIZE + 1 times
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;

    return EXIT_SUCCESS;

记住最后一张卡片

#include <iostream>
#include <random>

using namespace std;

class CardMachine 
    static unsigned constexpr DECK_SIZE = 4;
    int cards[DECK_SIZE] = 1,2,3,4;
    int lastCard = -1;
public:
    int getCard() 
        int const RANDOM_INDEX = rand()%DECK_SIZE;
        if (lastCard == RANDOM_INDEX) 
            return getCard();
        
        lastCard = cards[RANDOM_INDEX];
        return lastCard;
    
    
    void shuffle() 
        lastCard = -1;
    
;

int main()

    CardMachine cardMachine = CardMachine();
    
    cout << "Shuffled - Random order, and still no duplicates, but only able to produce 2:" << endl;
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;

    cout << "Shuffled. Random order, and still no duplicates:" << endl;
    cardMachine.shuffle(); // Causes potential duplicates if getCards 3+ times
    cout << cardMachine.getCard() << endl;
    cout << cardMachine.getCard() << endl;

    return EXIT_SUCCESS;

所有这些解决方案都使用一个类来保存getCard 中使用的状态,以确保我们获得正确的行为。

【讨论】:

非常感谢,你是天使,但这对我来说有点太复杂了..我什至还没有学习过课程..你能看看我对我的帖子的回答。我已经更新了我的代码。它可以按照我的意愿为我提供一个随机值,但是又出现了另一个问题。决定获胜者...我认为这与我缩短数组有关...谢谢。 @gunnar20008 一个类提供了一个抽象,它对类的用户隐藏了不必要的细节。在这里,用户(即使您同时编写 main 类和 card 类)只需要了解 getCard 将在正确调用时返回非重复卡(例如,在需要时之前调用 shuffle)。如果你想用没有关联数据/状态的普通函数来做这种事情,你可以创建全局变量来保存状态。例如,在最后一个选项中,您可以在函数之外声明 int lastCard = -1 以及 cardsDECK_SIZE @gunnar20008 我会声明,将其用作全局状态的函数正上方的全局状态/数据存在任何人都可以访问的问题,或者,如果不是const,更改。将数据放在函数附近将减少代码用户意外使用它或对它存在的原因感到困惑的机会。您可能拥有带有适当换行符的 unsigned const DECK_SIZE = 4; int cards[DECK_SIZE] = 1,2,3,4; int lastCardIndexExclusive = DECK_SIZE; int getCard() ... void shuffl() ...(如果您要使用倒数第二个解决方案)。

以上是关于数组,避免拉取 Duplicates,简单代码,C++的主要内容,如果未能解决你的问题,请参考以下文章

26. Remove Duplicates from Sorted Array

CF978A Remove Duplicates数组操作/STL

[LeetCode]80. Remove Duplicates from Sorted Array II删除数组中的重复值

git如何避免代码冲突

LeetCode-Kotlin-Array-2-Remove Duplicates from Sorted Array

leetCode-数组:Remove Duplicates from Sorted Array