Я думал об этой интересной проблемы еще немного и придумал решение.
Проблема в корне дерево структурирована, независимо от того, древовидного метода вы в конечном итоге с помощью:
- фактического типа данных дерева (которое, как я сначала решил, но он был гораздо более многословны)
- рекурсия
- имитация рекурсии с использованием стеков (что я и закончил в конечном итоге).
Я буду использовать следующий список расширенного списка слов, так как он указывает на некоторые крайние случаи, которые делают другие решения не:
li = ['First',
'FirstSecond',
'FirstSecondFirst',
'FirstSecondFirstly',
'FirstSecondThird',
'FirstFoo',
'FirstBarracudaSphyraena',
'xyz',
'xy',
'12345',
'123',
'1',
'FireTruckGarage',
'FireTruck',
'Fire']
Хитрость заключается в заметив, что каждый раз, когда есть потенциал удлинение префикса, мы должны сохранить предыдущий префикс в стеке префикса (здесь prefixes
), который содержит все префиксы, которые до сих пор не исчерпаны. После того, как мы сделали некоторые из «более глубоких» слов - в смысле того, чтобы быть узлами глубже по дереву, нам может потребоваться отступить и снова использовать старый префикс для более короткого слова.
После того, как встречается слово, которое не префикс текущего префикса, мы должны выставить стек префиксов, пока мы не достигнем того, что делает префикс слова и продолжить оттуда.
def ambiguate(words):
output = {}
prefixes = ['']
prefix = prefixes[0]
for item in sorted(set(words)):
backtracked = False
while not item.startswith(prefix):
prefix = prefixes.pop()
backtracked = True
# If we have backtracked, we put back the current prefix onto the
# prefix stack since we may have to use it later on.
if backtracked:
prefixes.append(prefix)
# Construct new output and a new prefix and append it to the
# prefix stack
output[item] = item.replace(prefix, '', 1)
prefix = item
prefixes.append(prefix)
return output
Продолжительность:
print(ambiguate(li))
Урожайность:
{'1': '1',
'123': '23',
'12345': '45',
'Fire': 'Fire',
'FireTruck': 'Truck',
'FireTruckGarage': 'Garage',
'First': 'First',
'FirstBarracudaSphyraena': 'BarracudaSphyraena',
'FirstFoo': 'Foo',
'FirstSecond': 'FirstSecond',
'FirstSecondFirst': 'First',
'FirstSecondFirstly': 'ly',
'FirstSecondFourth': 'Fourth',
'FirstSecondThird': 'FirstSecondThird',
'a': 'a',
'abc': 'bc',
'xy': 'xy',
'xyz': 'z'}
может посмотреть на различные "наибольшую общую подпоследовательность" вопросы здесь. –
Похоже, что список проходит по порядку, а операнды - только последовательные, это правильно? – sal
это почти как «противоположность квалификации» .... как почти исключая пространства имен (я не делаю этого, но это почти то, что мне кажется). – joefromct