2016-07-26 4 views
3

Две пары: если есть две пары костей с одинаковым числом, игрок набирает сумму этих кубиков. Если нет, игрок оценивает 0. Например, 1, 1, 2, 3, 3, помещенные на «две пары», дают 8.нахождение двух пар из целочисленного массива из двух элементов

примеры: 1,1,2,3,3 результаты 8 1, 1,2,3,4 Результаты 0 1,1,2,2,2 результаты 6

Как это можно найти эффективно?

Я использую следующий код, чтобы найти единственную пару

int max_difference = 0; 
int val1 = 0 , val2 = 0; 
Arrays.sort(dice); 
for (int i = 0; i < dice.length - 1; i++) { 
    int x = dice[i+1] - dice[i]; 
    if(x <= max_difference) { 
     max_difference = x; 
     val1 = dice[i]; 
     val2 = dice[i+1]; 

    } 
} 
pairScore = val1 + val2; 
+1

«две пары» = 2 x 2 кости с одинаковым значением? Итак, если у меня есть 1, 1, 2, 3, 4, результат равен 0? Что насчет 1, 1, 1, 2, 2? И 1, 1, 1, 1, 2? – Mark

+0

@Mark это должно привести к сумме обоих средств 6 (1 + 1 + 2 + 2) –

+0

В этом случае должно быть 6? 1, 1, 1, 2, 2? Значит, не имеет значения, что есть 3 1s, которые все еще считаются парой? – Mark

ответ

3

Я хотел бы использовать частотную карту, то есть номер ключа и значение счетчика (так Map<Integer, Integer>). Однако, поскольку он используется для кубиков, вы можете упростить это, используя массив с длиной, равной максимальному значению кости (6 для стандартных кубиков). Затем проверьте частоты для каждого номера и получите количество пар из него.

Пример:

int[] diceFrequency = new int[6]; 

//assuming d is in the range [1,6] 
for(int d : dice) { 
    //increment the counter for the dice value 
    diceFrequency[d-1]++; 
} 

int numberOfPairs = 0; 
int pairSum = 0; 

for(int i = 0; i < diceFrequency.length; i++) { 
    //due to integer division you get only the number of pairs, 
    //i.e. if you have 3x 1 you get 1 pair, for 5x 1 you get 2 pairs 
    int num = diceFrequency[i]/2; 

    //total the number of pairs is just increases 
    numberOfPairs += num; 

    //the total value of those pairs is the dice value (i+1) 
    //multiplied by the number of pairs and 2 (since it's a pair) 
    pairSum += (i + 1) * 2 * num; 
} 

if(numerOfPairs >= 2) { 
    //you have at least 2 pairs, do whatever is appropriate 
} 
+0

hey diceFrequency [d-1] ++; что это делает? –

+0

diceFrequency [d-1] ++; что это делает? –

+0

'// увеличиваем счетчик для значения кости. Это написано в комментариях –

5

Нет необходимости, чтобы сделать это так сложно, так как вы ищете только для получившегося числа ...

int prev = 0; 
int result = 0; 
int pairs = 0; 

Arrays.sort(dice); 
for (int i = 0; i < dice.length; i++) 
{ 
    int current = dice[i]; 
    if (current == prev) 
    { 
     result += current*2; 
     pairs++; 
     prev = 0; 
    } 
    else prev = current; 
} 

if (pairs == 2) return result; 
else return 0; 
3

Как насчет использования HashMap, как показано ниже?

public static void main(String[] args) { 
    List<Integer> list = Lists.newArrayList(1, 1, 2, 3, 3, 4); 
    Map<Integer, Integer> map = Maps.newHashMap(); 

    int result = 0; 

    for (int i : list) { 
     int frequency = (int) MapUtils.getObject(map, i, 0); 

     if (frequency < 2) { 
      map.put(i, ++frequency); 
     } 
    } 

    for (Map.Entry<Integer, Integer> entry : map.entrySet()) { 
     if (entry.getValue() > 1) { 
      result += entry.getKey() * entry.getValue(); 
     } 
    } 

    System.out.println(result); 
} 
+0

AFAIK такой вид карты называется частотной картой (только для справки о будущем :)). Кроме того, вы могли бы оптимизировать второй цикл с помощью 'entrySet()', так как тогда вам не придется выполнять дополнительные поиски. – Thomas

+0

KeySet() заменяется на entrySet(), как сказал @Thomas.Спасибо за совет. – freeism

+0

Когда у вас есть полный дом (например, 2 2 2 3 3), ваш код подсчитывает все кости, он, вероятно, должен считать только два из двух. –

1
public static void main(String[] args) { 
    List<Integer> list = Lists.newArrayList(1, 1, 2, 3, 3); 
    Map<Integer, Integer> map = new HashMap<>(); 

    int count= 0; 

    for (int num : list) 
     if(map.containsKey(num)) 
      map.put(num , map.get(num)+1); 
     else 
      map.put(num , 1); 

    for (int num : map.keySet()) { 
     if (map.get(num) > 1) { 
      count= count+ (num * map.get(num)); 
     } 
    } 

    System.out.println(count); 
} 
1

Я надеюсь, я мог бы понять проблему. Поэтому мы можем использовать эту часть кода.

List<Integer> diceList = new ArrayList<Integer>(); 
    diceList.add(1); 
    diceList.add(1); 
    diceList.add(2); 
    diceList.add(4); 
    diceList.add(3); 
    diceList.add(3); 
    diceList.add(6); 
    diceList.add(8); 

    Integer prev = null, score = 0; 

    boolean flag = false; 
    for (Integer val : diceList) { 
     if (prev == null || !prev.equals(val)) { 
      if (flag) { 
       score = score + prev; 
       flag = false; 
      } 
      prev = val; 

     } else if (prev == val) { 
      score = score + prev; 
      flag = true; 
     } 
    } 
    System.out.println(score); 
Смежные вопросы