- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
# -*- coding: utf-8 -*-
# На входе: не пустой b-массив
# На выходе: словарь из 1-ого элемента {самый часто встречающийся элемент:количество}
# 1. Сначала составляем словарь, потом ищем максимум и возвращаем
def Freq1(b):
assert len(b) > 0
d = {}
for x in b: # Пробегаем в цикле исходный массив
d[x] = d[x] + 1 if d.has_key(x) else 1 # Если ключ уже есть, прибавляем 1, если нет, записываем 1
v = max(d, key=d.get) # v ключ из словаря соответствующий максимальному значению
return {v:d[v]} # Возвращаем ответ
# 2. Ищем максимум прямо при составлении словаря
def Freq2(b):
d = {}
m, i = 0, 0 # Максимальная частота и индекс в словаре
for x in b: # Пробегаем в цикле исходный массив
d[x] = d[x] + 1 if d.has_key(x) else 1 # Если ключ уже есть, прибавляем 1, если нет, записываем 1
if d[x] > m:
m, i = d[x], x # Запоминаем максимум и его индекс
return {i:m}
# 3. Без использования словаря (сложность квадратичная - "тупой метод")
def Freq3(b):
m, i = 0, 0 # Максимальная частота и соответствующее ему значение
for x in b:
c = b.count(x) # Сколько раз встречается x в массиве b?
if c > m:
m, i = c, x
return {i:m}
# Проверка (примитивный unit-тест)
def Check(inData, expected):
assert Freq1(inData) == expected
assert Freq2(inData) == expected
assert Freq3(inData) == expected
Check(["banana", "banana", "apple", "banana", "banana", "apple", "onion"], {'banana': 4})
Check([2, 3, 9, 3, 6, 6], {3: 2})
Check([True, True, True, False, False, True], {True: 4})
Самый часто встречающийся элемент в массиве (3 способа).
Везде сплошной говнокод. Как ПРАВИЛЬНО найти самый часто встречающийся элемент в массиве?
Наверное, можно ещё отсортировать массив и пробежать по нему храня текущий элемент и количество и обновляя соответствующие переменные?
Мистер Хэнки 09.10.2010 12:44 # +1
>>Наверное, можно ещё отсортировать массив и пробежать по нему храня текущий элемент и количество и обновляя соответствующие переменные?
сортировка требует времени
denis 09.10.2010 14:47 # −2
Например, строить сбалансированное бинарное дерево прямо при проходе массива, в узлах будет значение:количество?
У меня плохо с алгоритмами :)
Мистер Хэнки 09.10.2010 16:53 # +1
зачем переусложнять? "За деревьями леса не видно" ©
вам надо задачу решить или на девушку произвести впечатление уровнем владения алгоритмами и технологиями? так вроде как не этим впечатляют испокон веку :)
xXx_totalwar 09.10.2010 17:00 # 0
во-во поэтому советую ебануть теоркатом: катаморфизмы, анаморфизмы, хиломорфизмы, параморфизмы наконец.
denis 09.10.2010 17:02 # 0
В прошлый раз в задаче поиска элемента и вставки в массив её препод сказал, что бинарный поиск ещё кое-как подходит :)
Я написал 5 вариантов: http://stden.livejournal.com/397391.html
roman-kashitsyn 30.06.2015 12:05 # 0
1) массив совсем небольшой, и проще и быстрее всего прогнать итерацию insertion sort.
2) структура данных выбрана неверно, и нужно её менять целиком; например, использовать сортированный multiset.
denis 09.10.2010 14:47 # 0
telnet 09.10.2010 12:45 # 0
denis 09.10.2010 14:49 # 0
telnet 09.10.2010 16:25 # +2
denis 09.10.2010 14:51 # 0
intestinalbrain 30.06.2015 11:50 # +1
dict((Counter(b).most_common()[0],))
3_14dar 30.06.2015 12:22 # 0
Кортеж лишний
roman-kashitsyn 30.06.2015 12:21 # 0
Если это лаба, то пофигу, лишь бы не квадратично.
Если бы это нужно сделать один раз в реальной жизни, я бы сделал так:
1) строим хэш таблицу со счётчиками за амортизированное O(N)
2) преобразуем её в массив пар за O(N)
3) строим max heap по частотам за O(log N)
4) вершина хипа - ответ за O(1)
Такой алгоритм работает за амортизированное O(N). Я почти уверен, что питоний Counter, упомянутый выше, примерно так и работает.
Если операция частая и/или может затрагивать подмассивы, гуглите Range Mode Query.
roman-kashitsyn 30.06.2015 12:27 # 0
За O(N), конечно.