Подсчет количества вхождений каждого элемента в списке - PullRequest
5 голосов
/ 29 июня 2009

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

Apple
Nokia
Samsung
Apple
LG
Nokia
HTC
Android
Apple
Nokia
Nokia
Apple
Samsung

Мне нужно построить любую структуру данных, предпочтительно карту с такими деталями, как

Apple,4
Nokia,4
Samsung,2
LG,1
Android,1

Я не уверен, является ли это оптимальным. Есть ли лучшее решение, чем это?
На самом деле я еще не написал выше в виде кода. Так что лучший код тоже поможет.

Ответы [ 6 ]

5 голосов
/ 29 июня 2009

Да, я бы использовал Map<String, Integer>. Я бы обернул add примерно так:

private static void incrementValue(Map<String, Integer> counters, String toAdd) {
    Integer currValue = counters.get(toAdd);
    if (currValue == null)
        counters.put(toAdd, 1);
    else
        counters.put(toAdd, currValue+1);
}

или без дженериков:

private static void incrementValue(Map counters, String toAdd) {
    Integer currValue = (Integer) counters.get(toAdd);
    if (currValue == null)
        counters.put(toAdd, 1);
    else
        counters.put(toAdd, currValue+1);
}
4 голосов
/ 29 июня 2009

Поскольку респондент упомянул, что не могут использоваться дженерики, поскольку целевой платформой была Java 1.4, можно использовать Коллекции Apache Commons , в которых не используются дженерики.

В ответе от pjp упоминается, что можно использовать сумку.

Оказывается, у коллекций Apache Commons есть Bag, который имеет метод getCount, который будет возвращать счет определенного объекта, который был добавлен в Bag.

Ниже приведен пример того, что add s некоторые Integer возражают против HashBag и подсчитывают, сколько из каждого Integer объекта это Bag содержит:

Bag b = new HashBag();

b.add(Integer.valueOf(1));
b.add(Integer.valueOf(2));
b.add(Integer.valueOf(2));
b.add(Integer.valueOf(3));

System.out.println("Count for 1: " + b.getCount(Integer.valueOf(1)));
System.out.println("Count for 2: " + b.getCount(Integer.valueOf(2)));
System.out.println("Count for 3: " + b.getCount(Integer.valueOf(3)));

Результаты были:

Count for 1: 1
Count for 2: 2
Count for 3: 1

(Я должен добавить заявление об отказе от ответственности за то, что этот код на самом деле был скомпилирован и запущен на Java 6, но я полагаю, что я использовал только те функции, которые присутствовали в 5-дневной версии до Java).

1 голос
/ 29 июня 2009

Откуда поступают данные? Если дБ - вы можете сделать это очень легко в запросе на бэкэнд с группой по.

0 голосов
/ 29 июня 2009

Самая естественная структура для этого - сумка aka a Multiset.

Сумка - это, по сути, функция от объекта к счету.

В коллекциях Google есть Multiset, однако вы можете легко создать свою собственную, используя HashMap.

http://google -collections.googlecode.com / SVN / багажник / Javadoc / index.html? COM / Google / общие / собирать / Multiset.html

0 голосов
/ 29 июня 2009

Помимо решений, которые были опубликованы, первое, что приходит мне в голову, - это составить таблицу «код-значение» и закодировать список с помощью кодов. Это было бы очень экономно.

0 голосов
/ 29 июня 2009

Карта, кажется, путь. Прямой доступ:)

Ключ: Элемент значение: число вхождений или список с индексами элемента в списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...