《Cracking the Coding Interview》——第8章:面向对象设计——题目1

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 }
原文地址:https://www.cnblogs.com/zhuli19901106/p/3683465.html