Алгоритм получился таким (привожу почти такой же код на Python, который писал карандашом и потом в классе).
slog_start = 0
i = 0
while i < len(word):
if word[i] in vowels_set:
vowel_pos = i
i += 1
while i < len(word):
if word[i] in vowels_set:
if i - vowel_pos == 1:
hyphens.append(i)
elif i - vowel_pos == 2:
hyphens.append(i - 1)
else:
hyphens.append(vowel_pos + 2)
Тут я понял: достаточно знать расстояние между соседними гласными (находятся ли они в позициях А И б) – если он равен 1, вставить передача на позиции бесли равно 2, то в позиции б − 1, иначе [т.е. когда расстояние больше 2] на позиции А + 2.
Оказывается, этот код Python:
word = input()
vowels_set = set('аеёиоуыэюяАЕЁИОУЫЭЮЯ')
vowels = []
for i in range(len(word)):
if word[i] in vowels_set:
vowels.append(i)
import collections
hyphens = collections.deque()
for i in range(1, len(vowels)):
a, b = vowels[i-1], vowels[i]
if b - a == 1:
hyphens.append(b)
elif b - a == 2:
hyphens.append(b - 1)
else:
hyphens.append(a + 2)
for i in range(len(word)):
if len(hyphens) and hyphens[0] == i:
print('-', end = '')
hyphens.popleft()
print(word[i], end = '')
word = input()
vowels_set = set('аеёиоуыэюяАЕЁИОУЫЭЮЯ')
prev_vowel = len(word)
for i in range(len(word)):
if word[i] in vowels_set:
prev_vowel = i
break
import collections
hyphens = collections.deque()
for i in range(prev_vowel + 1, len(word)):
if word[i] in vowels_set:
a, b = prev_vowel, i
if b - a == 1:
hyphens.append(b)
elif b - a == 2:
hyphens.append(b - 1)
else:
hyphens.append(a + 2)
prev_vowel = i
for i in range(len(word)):
if len(hyphens) and hyphens[0] == i:
print('-', end = '')
hyphens.popleft()
print(word[i], end = '')
Осталось только добавить поддерживать буквы «у», «б» и «б».
Для этого нужно немного изменить строку условий, начинающуюся с if b - a == 1:
:
for i ...:
...
if b - a == 1:
hyphens.append(b)
else:
for j in reversed(range(a + 1, b)):
if word[j] in specials_set: # specials_set = set('йьъЙЬЪ')
hyphens.append(j + 1)
break
else:
if b - a == 2:
hyphens.append(b - 1)
else:
hyphens.append(a + 2)
word = input()
vowels_set = set('аеёиоуыэюяАЕЁИОУЫЭЮЯ')
specials_set = set('йьъЙЬЪ')
prev_vowel = len(word)
for i in range(len(word)):
if word[i] in vowels_set:
prev_vowel = i
break
pos = 0
for i in range(prev_vowel + 1, len(word)):
if word[i] in vowels_set:
a, b = prev_vowel, i
if b - a == 1:
print(word[pos:b], end = '-')
pos = b
else:
for j in reversed(range(a + 1, b)):
if word[j] in specials_set:
print(word[pos:j + 1], end = '-')
pos = j + 1
break
else:
if b - a == 2:
print(word[pos:b - 1], end = '-')
pos = b - 1
else:
print(word[pos:a + 2], end = '-')
pos = a + 2
prev_vowel = i
print(word[pos:])
В заключении отвечу на возможный вопрос “зачем все это?”, ведь есть алгоритм П. Христова в модификации Дымченко и Варсанофьева, который, кроме того, применяемый не только для русского, но и для английского. Ну, во-первых, на самом деле он не подходит для английского из-за особенностей этого языка. Во-вторых, некоторые правила в нем довольно сомнительны, например, правило «ghs-ssg» приводит к фальшивый расшифровка слова «отклонить». И в-третьих, предложенный мной алгоритм гораздо быстрее.
PS Кстати, буду признателен, если кто-нибудь даст ссылку на оригинальный алгоритм П. Христова, т.к. Интересно, какие изменения внесли Дымченко и Варсанофьев.
Поиск по СПП список всех русских слов было найдено не очень большое количество слов с 5 последовательными согласными {например: агентство, ангстрем, бодрствование, интеллигенция}. В таких случаях (т. е. когда расстояние между соседними гласными равно 6) в позициях следует ставить дефис А + 3 или [что то же самое] б − 3.
Также можно комбинировать случаи, когда расстояние между гласными равно 1 или 2: в этих двух случаях на позиции ставится дефис А + 1.
vowels_set = set('аеёиоуыэюяАЕЁИОУЫЭЮЯ')
specials_set = set('йьъЙЬЪ')
word = input()
prev_vowel = len(word)
for i in range(len(word)):
if word[i] in vowels_set:
prev_vowel = i
break
pos = 0
for i in range(prev_vowel + 1, len(word)):
if word[i] in vowels_set:
a, b = prev_vowel, i
for j in reversed(range(a + 1, b)):
if word[j] in specials_set:
npos = j + 1
break
else:
if b - a <= 2:
npos = a + 1
elif b - a >= 6:
npos = b - 3
else:
npos = a + 2
print(word[pos:npos], end = '-')
pos = npos
prev_vowel = i
print(word[pos:])