Как проверить, сколько символов переменная имеет общего с другой переменной - PullRequest
0 голосов
/ 03 декабря 2018

Если у меня есть две переменные, и я хочу посмотреть, сколько у них общих символов, что бы я сделал, чтобы получить число из которых было неверным?например:

a = "word"
b = "wind"
a - b = 2

есть ли способ сделать это или сделать то, что выше работы?

Редактировать: это также должно учитывать порядок при расчете

Edit2: все это должно получиться, как показано ниже

a = bird
b = word
<program to find answer> 2


a = book
b = look
<program to find answer> 3


a = boat
b = obee
<program to find answer> 0

a = fizz
b = faze
<program to find answer> 2

Ответы [ 4 ]

0 голосов
/ 03 декабря 2018

Подсчитайте общие символы и вычтите это из длины более длинной строки.Основываясь на ваших изменениях и комментариях, я думаю, что вы ищете это:

def find_uncommon_chars(word1, word2):
    # select shorter and longer word
    shorter = word1
    longer = word2
    if len(shorter) > len(longer):
        shorter = word2
        longer = word1

    # count common chars
    count = 0
    for i in range(len(shorter)):
        if shorter[i] == longer[i]:
            count += 1
    # if you return just count you have number of common chars
    return len(longer) - count
0 голосов
/ 03 декабря 2018

Это может применяться не во всех случаях, но если вы хотите сравнить символы, вы можете использовать set:

a = "word"
b = "wind"

diff = set.intersection(set(a),set(b))
print(len(diff))
>> 2

Это игнорирует последовательности, когда вы группируете их в набор уникальных символов.

Другая интересная стандартная библиотека модулей Python, которую вы можете использовать: difflib.

from difflib import Differ

d = Differ()

a = "word"
b = "wind"

[i for i in d.compare(a,b) if i.startswith('-')]
>>['- o', '- r']

difflib, по сути, предоставляет методы для сравнения последовательностей, таких как строки.Из вышеприведенного объекта Differ вы можете сравнить 2 строки и определить символы, которые добавляются или удаляются для отслеживания изменений из строки a в строку b.В приведенном примере понимание списка используется для фильтрации символов, которые удалены из a до b, вы также можете проверить символы, которые начинаются с +, для добавляемых символов.

[i for i in d.compare(a,b) if i.startswith('+')]
>>['+ i', '+ n']

Или символы, общие для обеих последовательностей адресации

Как проверить, сколько символов у переменной общего с другой переменной

common = [i for i in d.compare(a,b) if i.startswith('  ')]
print(common, len(common))
>> ['  w', '  d'] 2

Подробнее оDiffer объект здесь

0 голосов
/ 03 декабря 2018

То, что вы описали, нужно, чтобы метрика расстояния редактирования между словами.Было упомянуто расстояние Хемминга, однако оно не может правильно учитывать слова различной длины, поскольку учитывает только подстановку.Другие общие метрики включают в себя «самую длинную общую подстроку», «расстояние Левенштейна», «расстояние Яро» и т. Д.

Ваш вопрос, по-видимому, описывает расстояние Левенштейна, которое определяется минимальным количеством правок, доступных для редактирования одного символа.одно слово из другого (вставки, удаления или замены).Страница wikipedia для этого достаточно тщательна, если вы хотите прочитать и понять больше по теме (или перейти к касательной Википедии), но что касается кодирования, то в pip уже есть библиотека:pip install python-Levenshtein, который реализует алгоритм в c для более быстрого выполнения.

Пример:

Вот рекурсивная реализация из кода Розетты с кучей комментариев, чтобы помочь вам понять, как это работает ..

from functools import lru_cache
@lru_cache(maxsize=4095) #recursive approach will calculate some substrings many times, 
                         # so we can cache the result and re-use it to speed things up.
def ld(s, t):
    if not s: return len(t) #if one of the substrings is empty, we've reached our maximum recursion
    if not t: return len(s) # the difference in length must be added to edit distance (insert that many chars.)

    if s[0] == t[0]: #equal chars do not increase edit distance
        return ld(s[1:], t[1:]) #remove chars that are the same and find distance
    else: #we must edit next char so we'll try insertion deletion and swapping
        l1 = ld(s, t[1:]) #insert char (delete from `t`)
        l2 = ld(s[1:], t) #delete char (insert to `t`)
        l3 = ld(s[1:], t[1:]) #swap chars
        #take minimum distance of the three cases we tried and add 1 for this edit
        return 1 + min(l1, l2, l3) 

и протестировать его:

>>>ld('kitten', 'sitting') #swap k->s, swap e->i, insert g
Out[3]: 3
0 голосов
/ 03 декабря 2018

Вы можете сделать что-то вроде этого:

sum(achar != bchar for achar, bchar in zip(a,b))

, который будет работать, когда строки имеют одинаковую длину.Если они могут иметь разную длину, то вы также можете учесть это:

sum(achar != bchar for achar, bchar in zip(a,b)) + abs(len(a) - len(b))

Хотя это позволит словам совпадать только в их начале, так что разница между wordy и word будетбудет 1, тогда как разница между wordy и ordy будет 5. Если вы хотите, чтобы эта разница была 1, вам понадобится немного более сложная логика.

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