2014-04-23 17:32
题目:请设计一个数据结构来模拟一副牌,你要如何用这副牌玩21点呢?
解法:说实话,扑克牌的花样在于各种花色、顺子、连对、三带一、炸弹等等,如果能设计一个数据结构,让判断这些特征的代码变得很好写,那就能满足题意要求了。我只是勉强实现了几个基本功能,包括抽牌、洗牌、切牌,用的是单向链表。至于要拿这个打斗地主、黑桃五之类的还是算了吧。
代码:
1 // 8.1 Implement a class to simulate a deck of cards 2 #include <iostream> 3 #include <string> 4 #include <unordered_set> 5 using namespace std; 6 7 struct Poker { 8 int index; 9 Poker(int _index = 0): index(_index) {}; 10 11 friend ostream& operator << (ostream &, const Poker &); 12 }; 13 14 ostream& operator << (ostream &cout, const Poker &p) 15 { 16 cout << '['; 17 if (p.index < 0 || p.index > 53) { 18 cout << "ERROR"; 19 } else if (p.index == 52) { 20 cout << "BLACK JOKER"; 21 } else if (p.index == 53) { 22 cout << "RED JOKER"; 23 } else { 24 switch(p.index / 13) { 25 case 0: 26 cout << "SPADE "; 27 break; 28 case 1: 29 cout << "HEART "; 30 break; 31 case 2: 32 cout << "CLUB "; 33 break; 34 case 3: 35 cout << "DIAMOND "; 36 break; 37 } 38 switch(p.index % 13) { 39 case 0: 40 cout << 'A'; 41 break; 42 case 1: 43 case 2: 44 case 3: 45 case 4: 46 case 5: 47 case 6: 48 case 7: 49 case 8: 50 cout << char('1' + p.index % 13); 51 break; 52 case 9: 53 cout << "10"; 54 break; 55 case 10: 56 cout << 'J'; 57 break; 58 case 11: 59 cout << 'Q'; 60 break; 61 case 12: 62 cout << 'K'; 63 break; 64 } 65 } 66 cout << ']'; 67 68 return cout; 69 } 70 71 struct PokerListNode { 72 Poker p; 73 PokerListNode *next; 74 PokerListNode(int _index): p(_index), next(nullptr) {}; 75 }; 76 77 class DeckOfPoker { 78 public: 79 DeckOfPoker() { 80 int i; 81 82 head = tail = nullptr; 83 for (i = 0; i < 54; ++i) { 84 if (head == nullptr) { 85 head = tail = new PokerListNode(i); 86 } else { 87 tail->next = new PokerListNode(i); 88 tail = tail->next; 89 } 90 dict.insert(i); 91 } 92 } 93 94 friend ostream& operator << (ostream &, const DeckOfPoker &); 95 96 Poker peekCard() { 97 if (head == nullptr) { 98 return Poker(-1); 99 } else { 100 return head->p; 101 } 102 } 103 104 Poker getCard() { 105 if (head == nullptr) { 106 return Poker(-1); 107 } else { 108 Poker p = head->p; 109 PokerListNode *ptr = head; 110 head = head->next; 111 delete ptr; 112 if (head == nullptr) { 113 tail = nullptr; 114 } 115 dict.erase(p.index); 116 117 return p; 118 } 119 } 120 121 void insertCard(int index) { 122 if (index < 0 || index > 53) { 123 return; 124 } 125 if (dict.find(index) != dict.end()) { 126 return; 127 } 128 129 PokerListNode *ptr = new PokerListNode(index); 130 if (head == nullptr) { 131 head = tail = ptr; 132 } else { 133 ptr->next = head; 134 head = ptr; 135 } 136 dict.insert(index); 137 } 138 139 bool empty() { 140 return head == nullptr; 141 } 142 143 void cutCards() { 144 if (head == tail) { 145 return; 146 } 147 148 PokerListNode *p1, *p2; 149 p1 = p2 = head; 150 while (p2->next != nullptr && p2->next->next != nullptr) { 151 p1 = p1->next; 152 p2 = p2->next->next; 153 } 154 PokerListNode *head2 = p1->next; 155 p1->next = nullptr; 156 157 PokerListNode *new_head, *new_tail; 158 159 new_head = new_tail = nullptr; 160 p1 = head; 161 p2 = head2; 162 while (p1 != nullptr && p2 != nullptr) { 163 if (new_tail == nullptr) { 164 new_head = new_tail = p1; 165 } else { 166 new_tail->next = p1; 167 new_tail = new_tail->next; 168 } 169 p1 = p1->next; 170 new_tail->next = nullptr; 171 172 new_tail->next = p2; 173 new_tail = new_tail->next; 174 p2 = p2->next; 175 new_tail->next = nullptr; 176 } 177 while (p1 != nullptr) { 178 new_tail->next = p1; 179 new_tail = new_tail->next; 180 p1 = p1->next; 181 new_tail->next = nullptr; 182 } 183 while (p2 != nullptr) { 184 new_tail->next = p2; 185 new_tail = new_tail->next; 186 p2 = p2->next; 187 new_tail->next = nullptr; 188 } 189 190 head = new_head; 191 tail = new_tail; 192 } 193 194 void shuffleCards() { 195 if (head == tail) { 196 // no card or one card only 197 return; 198 } 199 200 PokerListNode *p1, *p2; 201 202 p1 = p2 = head; 203 while (p2->next != nullptr && p2->next->next != nullptr) { 204 p1 = p1->next; 205 p2 = p2->next->next; 206 } 207 tail->next = head; 208 head = p1->next; 209 p1->next = nullptr; 210 tail = p1; 211 } 212 213 ~DeckOfPoker() { 214 PokerListNode *ptr; 215 216 while (head != nullptr) { 217 ptr = head; 218 head = head->next; 219 delete ptr; 220 } 221 tail = head; 222 dict.clear(); 223 } 224 private: 225 PokerListNode *head; 226 PokerListNode *tail; 227 unordered_set<int> dict; 228 }; 229 230 ostream& operator << (ostream& cout, const DeckOfPoker &deck) 231 { 232 cout << '{' << endl; 233 if (deck.head == nullptr) { 234 cout << "EMPTY" << endl; 235 } else { 236 PokerListNode *ptr = deck.head; 237 238 while (ptr != nullptr) { 239 cout << ptr->p << endl; 240 ptr = ptr->next; 241 } 242 } 243 cout << '}' << endl; 244 245 return cout; 246 } 247 248 int main() 249 { 250 DeckOfPoker *deck = new DeckOfPoker(); 251 string s; 252 int index; 253 254 while (cin >> s) { 255 if (s == "insert") { 256 cin >> index; 257 deck->insertCard(index); 258 } else if (s == "peek") { 259 cout << deck->peekCard() << endl; 260 } else if (s == "get") { 261 cout << deck->getCard() << endl; 262 } else if (s == "shuffle") { 263 deck->shuffleCards(); 264 } else if (s == "cut"){ 265 deck->cutCards(); 266 } else if (s == "print"){ 267 cout << *deck << endl; 268 } 269 } 270 delete deck; 271 272 return 0; 273 }