Как сделать специальную сортировку в C ++?

0

Как кто-то может сделать особый вид для следующей ситуации: есть колода карт. У вас есть 2D-массив, созданный из комбинации двух 1D-массивов: один, который представляет костюм, и другой, который представляет ранг как таковой:

string suit[4] = { "H", "D", "S", "C" };
string rank[13] = { "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2" };

Они объединяются для создания 2D-массива ([4][13]) с использованием этой комбинации,

suit[i1] + "-" + rank[i2]

После перетаскивания карт массив перестает быть порядком и должен быть возвращен в исходный порядок, где сначала идут Hearts, а затем Diamonds и т.д. Точно так же каждая группа должна сначала иметь туза, а затем короля и так далее.

Как можно сделать особый вид для этой ситуации?

Мои мысли:

Сначала нам нужно прочитать массив. Первый элемент следует сравнить со следующим. Трудная часть - это самое сравнение. Какие типы оснований мы должны использовать при сравнении. Предположим, что у нас есть DA, а затем H-2. Итак, сначала мы читаем первый символ строки, который является D, и сравниваем его со следующей. Если они одинаковы, мы должны перейти к третьей записи строки "DA". Если нет, сравним. Есть ли более простой способ? Как можно определить сравнение, говоря, что H> D и A> K? И как можно реализовать этот метод с использованием 2D-массива, потому что простая сортировка работает только на 1D массивах, а не на 2D.

  • 0
    поскольку вы используете c ++, почему бы не использовать вектор и просто написать функцию сравнения?
  • 0
    Разве вектор не эквивалентен 1D массиву? Кроме того, как я могу сделать сравнение элемента в записи с другим элементом в другой записи.
Показать ещё 11 комментариев
Теги:

2 ответа

2
Лучший ответ

Вот почему я рекомендовал создать класс карты.

class Card
{
  public:
    bool operator < (const Card& other_card) const;
//  private:
    suit m_suit;
    rank m_rank;
};

bool Card::operator<(const Card& other_card) const
{
  bool  is_less_than;
  if (m_suit == other_card.m_suit)
  {
      is_less_than = m_rank < other_card.m_rank;
  }
  else
  {
    is_less = m_suit < other_card.m_suit;
  }
  return is_less_than;
}

При перегрузке operator < вы можете использовать оператор для сравнения объектов Card:

Card player1;
player1.rank = two;
player1.suit = spade;
Card player2;
player2.rank = three;
player2.suit = spade;
Card player3;
player3.rank = 4;
player3.suit = club;

if (player1 < player2)
{
  cout << "player1 < player2\n";
}
else
{
  cout << "player1 not less than player2\n";
}

if (player 1 < player3)
{
  cout << "player1 < player3\n";
}
else
{
  cout << "player1 not less than player3\n";
}

Кроме того, методы sort и функции будут автоматически использовать этот метод, поэтому вам не нужно писать функцию сравнения.

Если вы также перегружаете operator==, вы можете легко определить все операторы сравнения:

operator!= : return !(*this == other_card);
operator>= : return !(*this <  other_card);
operator<= : return (*this < other_card) || (*this == other_card);
operator>  : return !(*this <= other_card);

Или вы включаете библиотеку Boost (заголовочный файл), которая будет кодировать все остальные операции для вас.

Редактировать 1: Палуба карт
Представление карты как единого объекта упрощает вашу программу. Card можно использовать в стандартных контейнерах:

typedef std::vector<Card> Card_Container;
Card_Container deck(52);
Card_Container poker_hand(5);
Card_Container blackjack_hand;

std::vector позволяет легко реализовать карточные контейнеры, которые нуждаются в динамической настройке размера, например, в BlackJack, War или "Go Fish".

Печать карточки
Вы можете перегрузить operator<< чтобы распечатать карту так, как вы хотите, в стиле, применимом ко всем картам. Это упрощает вывод:

cout << "Blackjack hand:\n";
for (Card_Container::iterator iter = blackjack_hand.begin();
     iter != blackjack_hand.end();
     ++iter)
{
  cout << *iter << "\n";
}
5

Основываясь на комментарии GWW:

enum suit { club, spade, diamond, heart };

enum rank {
   two, three, four, five, six, seven, eight,
   nine, ten, jack, queen, king, ace
};

using card = std::pair<suit, rank>;

int main ()
{
    std::vector<card> deck{
       {diamond, five}, {spade, ace},
       {club, two}, {spade, nine}
    };
    std::sort(deck.begin(), deck.end());
    for (auto c : deck)
        cout << c.first << " " << c.second << endl;
}

То есть, отдельное внутреннее представление из внешнего вида и использование enum для первого; пользовательский operator<< может позаботиться о последнем. card основанная на std::pair использует свой operator< который сравнивает лексикографически, что вы хотите, если я получу его правильно.

Это предполагает, что вы храните колоду в одномерном vector. Я думаю, что это было бы более удобно, чем двумерное в большинстве ситуаций. На самом деле, я не понимаю, почему вы настаиваете на 2D, когда хотите сортировать.

  • 0
    Я не совсем понимаю, что делает парная функция? И чтобы ответить на ваш вопрос: я настаивал на 2D-массиве для согласованности и ясности. Однако, как вы сказали, сортировка намного проще с массивом 1D.
  • 0
    pair @ user29568 - это не функция, это структура, которая содержит только два элемента. У него есть предопределенный operator< который позволяет сравнивать их, и это означает, что содержимое pair s может быть отсортировано с помощью функции std::sort .
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню