C++ Array Shuffle

后端 未结 10 1859
温柔的废话
温柔的废话 2021-01-07 14:06

I\'m fairly new to C++ and don\'t quite understand function parameters with pointers and references. I have an array of Cards that I want to shuffle using the Fisher-Yates

相关标签:
10条回答
  • 2021-01-07 14:51

    One immediate nitpick, you should always use the top-half of a random number because most implementations of random numbers have poorer randomness on the bottom half. So if long's are 32 bit you could use: k = (k >> 24) % 24 to get better randomness.

    Second, the problem here is you are not setting temp. Your code should have a line: temp = deck[deckSize];.

    Hope this helps.

    Edit:

    Further nitpick, your random number generator is also not big enough to sufficiently shuffle a deck of cards regardless of using the high bit or low bit. It only has 48bit long sequence, but to shuffle a deck you'd need at least a 226bit long sequence (52!, the number of ways to shuffle a deck, is a 226bit long number).

    0 讨论(0)
  • 2021-01-07 14:54

    People are complaining that you're not using containers and not declaring the size of your array. Don't worry about that, that's not the problem. Someone also said you're going past array boundaries, which you aren't. It's okay to have arrays with size not declared. It's also okay to have an array of pointers to Card. But the thing I don't get is why it crashes. Here's some sample code I wrote, based on your code:

    #include <stdio.h>
    #include <stdlib.h>
    #define DECK_SIZE 24
    void shuffle(int deck[]) {
        int n = DECK_SIZE, t;
        while (n > 1) {
            long k = lrand48() % DECK_SIZE;
            n--;
            t = deck[n];
            deck[n] = deck[k];
            deck[k] = t;
        }
    }
    int main(int argc, char **argv) {
        int deck[DECK_SIZE], i;
        for (i = 0; i < DECK_SIZE; ++i)
            deck[i] = i + 1;
        shuffle(deck);
        for (i = 0; i < DECK_SIZE; ++i)
            printf("%i\n", deck[i]);
        return 0;
    }
    

    Run it, it works perfectly fine. That means there is something else going on. Try printing the value of all the cards in your deck before you call shuffle to see if it segfaults there too, I suspect it would.

    However, there IS an error in your code. Your function does not shuffle correctly. The correct way to shuffle is not to swap each card with a card selected from the entire deck, but to swap each card at position N with an card selected from the range 0..N. If you swapped each card with a random card you get N^N possible outcomes, some of which overlap if you swap a card back to its original place. With a 3 card deck it's apparent that this is wrong because you will end up with 27 different shuffles, some of which are the same, even though there are 3!=6 permutations of 3 cards. The problem is that since 6 is not a factor of 27, some permutations are more likely than others. To avoid this, try doing it this way:

    void shuffle_correctly(int deck[]) {
        int i, t, k;
        for (i = 2; i < DECK_SIZE; ++i) {
            k = lrand48() % i;
            t = deck[i-1];
            deck[i-1] = deck[k];
            deck[k] = t;
        }
    }
    
    0 讨论(0)
  • 2021-01-07 14:57

    My C/C++ is rusty but I think your declaration:

    Card *deck[deckSize];
    

    is declaring an array of POINTERS to Cards. Don't you want this?

    Card deck[deckSize];
    

    and then declare shuffle:

    void shuffle (Card deck[]) 
    

    keep in mind arrays are 0-indexed. Not sure if you'd ever access the 24th element but that would be a boo-boo.

    0 讨论(0)
  • 2021-01-07 14:57
     Card *deck[deckSize];
    

    I think you want:

    Card *deck = new Card[deckSize];
    
    0 讨论(0)
提交回复
热议问题