2017-01-30 2 views
1

В настоящее время я пишу класс, который создает несколько рук, содержащих объекты карты, с помощью arrayLists. Я пытаюсь написать метод, который ищет arraylist (рука) и возвращает самую большую пару карт.Как найти максимальное значение любого дубликата в ArrayList

Вот что у меня есть сейчас, но это очень неэффективно:

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

Вы можете тривиально реализовать мультимножество с 'Map ', является ли Integer числом. Тогда вы можете просто перебрать его и найти самый большой счет. – Kevin

+0

Вы имеете в виду, что время выполнения неэффективно, или код является громоздким? – MeetTitan

+0

использование массив ..... – ZhongYu

ответ

1

Поскольку в обычных карточных играх есть только 13 различных ранжировок карт, можно избежать использования карт. Вам просто нужен счетчик частоты для ранжирования в массиве temp-массива 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 самый высокий (в моем примере ранга для тузов 12). Вы можете легко изменить это в соответствии с вашим ранжированием.

+0

'freq [c.getRank()] ++;' будет вырабатывать 'ArrayIndexOutOfBoundsException', когда' c.getRank() 'возвращает' 13', так как массив 'freq' имеет длина 13. Следовательно, последнее значение индекса, которое можно использовать, составляет '12'. – davidxxx

+0

Я заметил, что это для 0-12; это легко для OP изменить в соответствии с его требованиями. –

+0

Мне действительно нравится этот ответ, так как он использует массив для решения проблемы, которая была моим первоначальным намерением !. Я попробую это и отчитаюсь. – Wiz

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; 
+0

Поскольку мы хотим найти max-пару, мы могли бы просмотреть отсортированный список от n до 1. Как насчет изменения для цикла, подобного этому, для (int i = cards.size() - 1; i> = 0; i--)? – exiter2000

+0

@ exiter2000 Я предполагаю, что компаратор находится в порядке убывания, поэтому он ставит старшую карточку сначала – AdamSkywalker

+0

, она может вернуть что-то большее, чем пара - 3 или 4 вида – ZhongYu

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); 
1

кода кажется нормально, но это очень громоздко, как ваше повторение многих вещей, которые не должно быть.
В цикле вы можете использовать карту, чтобы связать номер карты с вступлением.
Таким образом, вы избегаете длинной серии заявлений 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; 
0

Вот как я бы подойти к этой проблеме:

1) Сортировать руку на рангу карты от наибольшего ранга наименьшего ранга.

2) Идите по картам в отсортированной руке, найдя! пример , когда рейтинг следующей карты совпадает с рангом этой карты. if (cards.get (i + 1) .getRank() == cards.get (i) .getRank())

3) Выполнено.

Обратите внимание, что приведенный выше код НЕ эффективен! Вы можете внести незначительные изменения, чтобы сохранить ранжирование карт между итерациями цикла, чтобы сделать код еще более эффективным.

Смежные вопросы