Есть очень необычная и как оказалось довольно сложная задачка. Дано: список фамилий. Требуется распределить их по буквенным группам аля А-В с таким расчетом например что если много фамилий начинающихся на А, В, Д, Е, Ц, и мало на остальные буквы, то группы должны сформироваться А-Б, В-Д, Е-Ж, З-Ц, Ч-Я. Мучаюсь с этим уже долго. Никак не могу придумать нормальный алгоритм... Единственное что я пока смог сделать это просто раскидать их на группы типа [ ( 'А' , [ 'Аааа', 'Аббб', ] ), ]. Также уточню что неважны буквы идущие после первой. Главное распределить по первой букве. Ну и я это делаю на питоне, но буду рад решению на любом языке (если конечно смогу его понять :D).
П.С. Вот, если поможет что я смог накидать. Это конечно не то что нужно, но кажется я на правильном пути...
def distribute(employees):
letters = []
for i in range(ord('А'), ord('Я') + 1):
c = chr(i)
c_employees = [e for e in employees if e[0].upper() == c]
letter = (c, c_employees)
letters.append(letter)
return letters
upd. Кажется решил.
def flatten(sequence):
for item in sequence:
if isinstance(item, collections.Iterable) and not isinstance(item, (str, bytes)):
yield from flatten(item)
else:
yield item
def distribute_by_letters(employees):
letters = []
count = 0
for i in range(ord('А'), ord('Я') + 1):
c = chr(i)
c_employees = [e for e in employees if e[0].upper() == c]
letter = (c, c_employees)
letters.append(letter)
if len(c_employees) != 0:
count += 1
avg = len(employees) / count
return (letters, round(avg))
def distribute_by_groups(letters_info):
letters, avg = letters_info
groups = []
i = 0
while i < len(letters):
group_employees = []
j = i
count = 0
while count < avg and j < len(letters):
group_employees.append(letters[j])
count += len(letters[j][1])
j += 1
empty_letters = itertools.takewhile(lambda l: len(l[1]) == 0, letters[j:])
group_employees.extend(list(empty_letters))
begin_letter = letters[i][0]
end_letter = group_employees[-1][0]
group_name = '%s-%s' % (begin_letter, end_letter)
i += len(group_employees)
group_employees = [l[1] for l in group_employees]
group_employees = list(flatten(group_employees))
group = (group_name, group_employees)
groups.append(group)
return groups