我目前正在编写类,使用arrayLists创建包含卡对象的多个手。我正在尝试编写一种方法来搜索arraylist(hand)并返回最大的一对牌。
以下是我现在的情况,但效率很低:
public int findPairRank() {
int one = 0, two = 0, three = 0, four = 0, five = 0, six = 0, seven = 0, eight = 0, nine = 0, ten = 0, eleven = 0, twelve = 0, thirteen = 0;
// loops through every card rank and adds +1 if it exists in the hand
for (int i = 0; i < cards.size(); i++) {
if (cards.get(i).getRank() == 1)
one++;
if (cards.get(i).getRank() == 2)
two++;
if (cards.get(i).getRank() == 3)
three++;
if (cards.get(i).getRank() == 4)
four++;
if (cards.get(i).getRank() == 5)
five++;
if (cards.get(i).getRank() == 6)
six++;
if (cards.get(i).getRank() == 7)
seven++;
if (cards.get(i).getRank() == 8)
eight++;
if (cards.get(i).getRank() == 9)
nine++;
if (cards.get(i).getRank() == 10)
ten++;
if (cards.get(i).getRank() == 11)
eleven++;
if (cards.get(i).getRank() == 12)
twelve++;
if (cards.get(i).getRank() == 13)
thirteen++;
}
ArrayList<Integer> list = new ArrayList<Integer>();
if (one == 2)
list.add(1);
if (two == 2)
list.add(2);
if (three == 2)
list.add(3);
if (four == 2)
list.add(4);
if (five == 2)
list.add(5);
if (six == 2)
list.add(6);
if (seven == 2)
list.add(7);
if (eight == 2)
list.add(8);
if (nine == 2)
list.add(9);
if (ten == 2)
list.add(10);
if (eleven == 2)
list.add(11);
if (twelve == 2)
list.add(12);
if (thirteen == 2)
list.add(13);
int max = 0;
for (int i = 0; i < list.size(); i++) {
if (list.get(i) > max)
max = list.get(i);
}
if (max > 0)
return max;
else
return 0;
}
答案 0 :(得分:1)
注意:更好地使用地图计数器解决方案。这个算法有效,但我不会用它。一开始看起来很不错,直到钟宇指出一个问题。
按值对牌进行排序,然后迭代直至找到一对
// copy items to new list to preserve initial order
List<Card> cards = new ArrayList(playerCards);
// sort cards by rank value from high to low
Collections.sort(cards, rankComparator);
int counter = 1; // number of cards of same rank
for (int i = 1; i < cards.size(); i++) {
if (cards.get(i).getRank() == cards.get(i-1).getRank()) {
counter++; // if card has same rank as previous, inc counter
} else { // if rank changed
if (counter == 2) { // if we had pair, return its rank
return cards.get(i-1).getRank();
} else { // start again
counter = 1;
}
}
}
return counter == 2 ? cards.get(i-1).getRank() : 0;
答案 1 :(得分:1)
代码似乎还可以,但是重复许多不应该的东西,这是非常麻烦的
在循环中,您可以使用Map将卡号与出现相关联
通过这种方式,您可以避免使用一长串if
语句。
代码看起来像这样:
List<Card> cards = ...
Map<Integer,Integer> occurrenceByNumber = new HashMap<>();
for (int i = 0; i < cards.size(); i++) {
Card card = cards.get(i);
Integer occurrence = occurrenceByNumber.get(card.getRank());
if (occurrence == null){
occurrence = 1;
}
else{
occurrence++;
}
occurrenceByNumber.put(card.getRank(), occurrence);
}
Integer maxNumber = null;
for (Entry<Integer, Integer> entry : occurrenceByNumber.entrySet()){
int occurrence = entry.getValue();
int number = entry.getKey();
if ( occurrence == 2 && (maxNumber == null || number> maxNumber) ){
maxNumber = number;
}
}
return maxNumber;
答案 2 :(得分:1)
由于普通纸牌游戏只有13种不同的卡片排名,因此可以避免使用地图。您只需要一个频率计数器,用于int[13]
(或甚至byte[13]
)临时数组的排名。这是一个例子:
public int findPairRank() {
int[] freq = new int[13];
for (Card c: cards) { //assuming you use Card objects
freq[c.getRank()]++;
}
for (int i = 12; i >= 0; i--) {
if (freq[i] == 2) return i;
}
return -1; //no pair found
}
*请注意,通常数字2卡的排名最低(在我的示例中排名= 0),而Ace是最高排名(在我的例子中,排名是A)是12。您可以根据您的排名设计轻松更改上述内容。
答案 3 :(得分:0)
ArrayList<Integer> hand = new ArrayList<Integer>(13);
for (int i = 0; i < cards.size(); i++) {
int x = cards.get(i).getRank();
if(x>0&&x<14) {
hand.set(i-1, hand.get(i-1)+1)); //increment values
}
}
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i=0; i<hand.size(); i++) {
if(hand.get(i)==2) {
list.add(i+1); //one will be at index 0, etc
}
}
return Collections.max(list);
答案 4 :(得分:0)
以下是我如何解决这个问题:
1)将卡牌等级从最高等级排序到最低等级。
2)在排序的手中迭代卡片,找到!第一个!例 当下一张牌的排名与此牌的排名相同时。 if(cards.get(i + 1).getRank()== cards.get(i).getRank())
3)完成。
注意,上面的代码效率不高!您可以进行微小的更改以保持循环迭代之间的卡排名,从而使代码更加高效。