如何在ArrayList中查找任何重复的最大值

时间:2017-01-30 20:17:08

标签: java collections

我目前正在编写类,使用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;
}

5 个答案:

答案 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)完成。

注意,上面的代码效率不高!您可以进行微小的更改以保持循环迭代之间的卡排名,从而使代码更加高效。