Слова для кадавра Python
Задание звучит так:
Напишите программу, которая определит слова, подходящие под некоторый шаблон словообразования, которым в данный момент владеет кадавр.
Обозначения в шаблоне: 1 — не гласная, 0 — гласная, ? — строго одна любая буква, * — любое количество любых букв, в том числе ни одной. Гарантируется, что * в шаблоне не более одной.
Примеры:
10?010
молоко
отруби
обрат
селёдка
буханка
головы
молоко
головы
1010*0
отруби
обрат
сельдь
хлеб
грузди
Есть нечего, значить!
Часть решения мне сразу пришла в голову:
lettersG = 'ауоыиэяюеё'
lettersN = 'бвгджзйклмнпрстфхцчшщ'
st = ''
while True:
checkW = input()
if checkW == '':
break
if len(checkW) < len(w) or len(checkW) > len(w):
continue
for i in range(len(w)):
if w[i] == '1':
if checkW[i] not in lettersN:
break
if w[i] == '0':
if checkW[i] not in lettersG:
break
if i == len(w) - 1:
st += ' ' + checkW
print(checkW)
if st == '':
print('Есть нечего, значить!')
Это решение даже проходит несколько тестов, но всё-таки два случая у меня не учитываются. То есть это символ '?', так как я считаю, что это бесполезно. А второй случай - если в шаблоне присутствует '*'. У меня нет никаких идей, что делать, если в шаблоне встречается звёздочка. Подскажите, пожалуйста
Ответы (2 шт):
Идея для звёздочки...
Разбить шаблон на 2 части по звёздочке. Затем левую часть шаблона сравнить с начальным куском слова такой же длины как и часть шаблона. Ну а правую часть шаблона аналогично, только с куском слова с конца.
def check_part(template, word):
lettersG = 'ауоыиэяюеё'
lettersN = 'бвгджзйклмнпрстфхцчшщ'
if (len(template) != len(word)):
return False
for t,w in zip(template, word):
if (t == "0" and w not in lettersG) or (t == "1" and w not in lettersN):
return False
return True
def check(template, word):
if "*" in template:
left, right = template.split("*", 1)
return check_part(left, word[:len(left)]) and check_part(right, word[len(word)-len(right):])
else:
return check_part(template, word)
check("10*10", "молоко")
Переводим слова на кадавр, меняем количество звездочек так, чтобы длина слова сравнялась с длиной шаблона, сравниваем слово с шаблоном. Примерно так:
inp = ['молоко','отруби','обрат','селёдка','буханка','головы']
pat = '10?010'
res = []
table = str.maketrans('ауоыиэяюеёбвгджзйклмнпрстфхцчшщьъ','0'*10 + '1'*23)
for w in inp:
t = w.translate(table)
p = pat.replace('*','*'*(len(w)-len(pat)+1))
if all(i in ['*','?',j] for i,j in zip(p,t)):
res.append(w)
print(res or 'Есть нечего, значит!') # ['молоко', 'головы']
и результаты для других шаблонов:
inp = ['отруби','обрат','сельдь','хлеб','грузди']
pat = '1010*0' # Есть нечего, значит!
pat = '011*0' # ['отруби']
pat = '11?*1' # ['хлеб']