0

I have an array that I need to sort. It is made using 2 other arrays using C++.

string deck[4][13];
string type[4] = {"Hearts","Diamonds","Spades","Clubs"};
string cards[13] = {"Ace","King","Queen","Jack","10","9","8","7","6","5","4","3","2"};

for (int i = 0; i<4; i++)
{
    for (int j=0; j<13 ; j++)
    {
        deck[i][j]=type[i]+"-"+cards[j];

        cout << deck[i][j] << " ";
    }

    cout << endl;
}

I am shuffling this deck and then trying to sort it again. I understand comparing the indexes of the deck to the indexes the other arrays is the easiest way but I don't understand how to do it. Thanks in advance for any help.

  • 2
    http://stackoverflow.com/questions/1380463/sorting-a-vector-of-custom-objects – IdeaHat Mar 17 '14 at 19:02
  • 2
    In your case, it looks like it makes the most sense to have cards that have both rank and suit. Then your sorting problem goes away since you have one array instead of two. – crashmstr Mar 17 '14 at 19:06
  • I don't understand. my deck is 1 array. I just need to sort it according to the arrays called type and cards (should of called them rank and suit). like ace > king > queen > jack > ... > 2 and hearts > diamonds > spades > clubs. – user3430298 Mar 17 '14 at 19:10
  • 1
    @user3430298 if you have a `struct` or `class` and it contains a `rank` and `suit`, your data is together in a single dimension array. You can then sort that array based on criteria that does not depend on an external array. – crashmstr Mar 17 '14 at 19:22

2 Answers2

2

Recommendation: create a card class and use std::vector.
This will reduce the complexity (and defects) of your program.

Arrays are difficult to use, so use std::vector. Since a card contains both a suit and a number, let us proceed in that manner:

class Card
{
  std::string    suit_text;
  std::string    card_value;
};

Given the above definition, one can make decks and player's hands as containers of Card:

std::vector<Card>  deck(52); // Allocate space for 52 cards in the deck.
std::vector<Card>  poker(5); // A poker hand consists of 5 cards.

The remaining code on how to use the card is left to the OP.

Edit 1: Base 52 math
Assigning a random suit and value to the cards can be thought of as selecting a random number between 0 and 51 (or 1 and 52). The trick is to convert the number into suit number and value number.

There are 13 cards in a suit, so card number / 13 will produce the suit number:

  suit_id = random_number / 13;
  card_value = random_number % 13;

Also, using std::bitset may help in determining which random numbers have already been generated.

crashmstr
  • 28,043
  • 9
  • 61
  • 79
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
1

Your situation requires a different approach than using strings to capture the suits and cards.

Your sorting order for the suits, "Hearts" > "Diamonds" > "Spades" > "Clubs" is easy to implement using numbers but require unnecessary complication when using strings.

Similarly for the cards.

My suggestion is to create enums that represent the suits and cards. Store those enums for all computations. When it's time for printing messages, have a function that returns a string given a card.

enum Suit { HEARTS, DIAMONDS, SPADES, CLUBS};
enum Card { ACE, KING, QUEEN, JACK, TEN, NINE, EIGHT, SEVEN, SIX, FIVE, FOUR, THREE, TWO};

struct DeckCard
{
   Suit suit;
   Card card;

   // Implement the < operator to make it easy to sort a deck of cards.
   bool operator<(DeckCard const& rhs) const
   {
      if ( this->suit != rhs.suit )
      {
         return (this->suit < rhs.suit);
      }
      return (this->card < rhs.card);
   }

   std::string toString()
   {
      return suiteToString() + "-" + cardToString();
   }
   std::string suiteToString()
   {
      switch ( suit )
      {
         case HEARTS:
            return "Hearts";

         case DIAMONDS:
            return "Diamonds";

         case SPADES:
            return "Spades";

         case CLUBS:
            return "Clubs";

         default:
      }
      return "Unknown Suit";
   }

   std::string cardToString()
   {
      switch ( card )
      {
         case ACE:
            return "Ace";

         case KING:
            return "King";

         case QUEEN:
            return "Queen";

         case JACK:
            return "Jack";

         case TEN:
            return "10";

         case NINE:
            return "9";

         case EIGHT:
            return "8";

         case SEVEN:
            return "7";

         case SIX:
            return "6";

         case FIVE:
            return "5";

         case FOUR:
            return "4";

         case THREE:
            return "3";

         case TWO:
            return "2";

      }

      return "Unknwon Card";
   }
};

DeckCard deck[4*13];

for (int i = 0; i<4; i++)
{
    for (int j=0; j<13 ; j++)
    {
        deck[i*13+j].suit = type[i];
        deck[i*13+j].card = cards[j];

        cout << deck[i*13+j].toString() << " ";
    }

    cout << endl;
}

// Sort the cards.
std::sort(deck[0], deck[51]);

You can also shuffle your cards using std::shuffle

Mooing Duck
  • 64,318
  • 19
  • 100
  • 158
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • "I am shuffling this deck and then trying to sort it again." Not sure exactly what the OP needs, but a mention of `std::shuffle`, `std::sort`, and `operator<` might not go amis. – Mooing Duck Mar 17 '14 at 19:50
  • @MooingDuck, good ideas. I edited the answer per your comments. – R Sahu Mar 17 '14 at 20:03