Наиболее частое частичное совпадение строк в списке строк

1

У меня есть большой список строк (не более 2k), и я хочу найти наиболее часто встречающееся партичное совпадение в списке. Например, я стараюсь удовлетворительно выполнить следующий тестовый пример.

data = [
    'abcdef',
    'abcxyz',
    'xyz',
    'def',
]
result = magic_function(data)
assert result == 'abc'

Я пробовал это с вдохновением из qaru.site/questions/10918744/..., но тот факт, что некоторые элементы в списке полностью разные, отбрасывает его.

def magic_function(data):
    return ''.join(c[0] for c in takewhile(lambda x: all(x[0] == y for y in x), zip(*data)))
  • 0
    что произойдет, если в ваших data также будет 'ape' - будет ли 'a' вашей магией? И если нет, то почему?
Теги:
python-3.x

1 ответ

1
Лучший ответ

Вам, вероятно, придется подкорректировать это и проверить его.

Я по существу питаю все частичные подстроки до длины каждого слова в data в Counter и создаю ранжирование, основанное на len(substring)*occurence - наложение штрафов только на 1 путем умножения на 0,1:

data = [
    'abcdef',
    'abcxyz',
    'xyz',
    'def',
]    

def magic(d):
    """Applies magic(tm) to the list of strings given as 'd'.
    Returns a list of ratings which might be the coolest substring."""
    from collections import Counter
    myCountings = Counter()

    def allParts(word):
        """Generator that yields all possible word-parts."""
        for i in range(1,len(word)):
            yield word[:i]

    for part in d:
        # count them all
        myCountings.update(allParts(part))

    # get all as tuples and sort based on heuristic length*occurences
    return sorted(myCountings.most_common(), 
                  key=lambda x:len(x[0])*(x[1] if x[1] > 1 else 0.1), reverse=True)

m = magic(data)    
print( m ) # use  m[0][0] f.e. 

Выход:

 [('abc', 2), ('ab', 2), ('a', 2), ('abcde', 1), ('abcxy', 1), 
  ('abcd', 1), ('abcx', 1), ('xy', 1), ('de', 1), ('x', 1), ('d', 1)]

Вам нужно будет немного изменить критерии сортировки и использовать только первый в результирующем списке, но вы можете использовать его как стартер.

Тонкая настройка может быть выполнена путем умножения длины на faktor, если вы предпочитаете более длинные из нескольких коротких - это зависит от ваших данных...

  • 0
    Круто, похоже, это хорошо работает! Я собираюсь сделать некоторые профилирование, чтобы посмотреть, можно ли улучшить его производительность, но я думаю, что это будет работать на данный момент. Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню