需要p语言解密帮助



我不知道你们是否熟悉p语言,或者这是我们国家才知道的东西。基本上,每次你在一个单词中遇到一个元音,你就把这个元音替换成同一个元音+ p +这个元音。

所以"家"在p语言中就是"hopomepe"。现在我的任务是破译p语言,并把用p语言写的句子变成正常的。

p = str(input())
for letter in range(1, len(p)):
if p[letter]=='.':
break
if p[letter-1]==p[letter+1] and p[letter]=='p':
p = p[:letter-1] + p[letter+1:]
print(p)

这是我到目前为止的代码,它工作,除了我不知道如何使它工作的双元音发音像'io'在蝎子(scoporpiopion)例如。

同样,当一个句子以元音开头时,该代码对该元音不起作用。例如,在我的代码中,"Apan epelepephapant"变成了"Apan elephant"。

和我的代码崩溃与字符串索引越界时,它没有结束在'。但是每次当我没有这个的时候它就会崩溃。"情况。

TLDR;我怎样才能改变我的代码,使它适用于双元音和在我的句子开头。

编辑:澄清一下,就像我的例子一样,组合元音应该算作一个元音。蝎子应该是Scoporpiopion而不是scoporpiopon,船应该是boapoat,靴子应该是boopoot,…

您可以使用正则表达式:

import re
def decodePLanguage(p):
return re.subn(r'([aeiou]+)p1', r'1', p, flags=re.IGNORECASE)[0]
In [1]: decodePLanguage('Apan epelepephapant')
Out[1]: 'An elephant'
In [2]: decodePLanguage('scoporpiopion')
Out[2]: 'scorpion'

使用re.subn函数替换所有的正则表达式匹配。

r'([aeiou]+)p1'中,[aeiou]+部分匹配连续的几个元音,1确保在p之后有相同的组合。

则使用r'1'将整个匹配替换为第一个元音组

EDIT: working code

def decipher(p):    
result = ''
while len(p) > 2:
# first strip out all the consecutive consonants each iteration
idx = 0
while p[idx].lower() not in 'aeiou' and idx < len(p) - 2:
idx += 1
result += p[:idx]
p = p[idx:]
# if there is any string remaining to process, that starts with a vowel
if len(p) > 2:
idx = 0
# scan forward until 'p'
while p[idx].lower() != 'p':
idx += 1
# sanity check
if len(p) < (idx*2 + 1) or p[:idx].lower() != p[idx+1:2*idx+1].lower():
raise ValueError
result += p[:idx]
p = p[2*idx+1:]
result += p
return result

在您的示例中输入'Apan epelepephapant',比较'A' == 'a'并得到False。你似乎想比较'a' == 'a',也就是每个str.lower()

似乎你也没有检查p之前和p之后的字符是否是元音;也就是说,如果您遇到字符串hph,如所写,您的函数将其解析为简单的h


以下代码的早期版本:

def decipher(p):    
while len(p) > 2:
if p[0].lower() in 'aeiou' and p[0].lower() == p[2].lower() and p[1] == 'p':
result += p[0]
p = p[3:]
else:
result += p[0]
p = p[1:]
result += p
return result

称为例如

p = str(input())
print(decipher(p))

由于@Kolmar已经给出了regex解决方案,我将添加一个没有regex的

为了帮助您理解这个问题,我将首先向您展示如何将正则字符串编码为p-language。在这种方法中,我使用itertools.groupby()根据是否为元音对字符串中的字符进行分组。此函数将具有相同键的连续元素分组在同一组中。
def p_encode(s):
vowels = {'a', 'e', 'i', 'o', 'u'}
s_groups = [(k, list(v)) for k, v in itertools.groupby(s, lambda c: c.lower() in vowels)]
# For scorpion, this will look like this:
# [(False, ['s', 'c']),
#  (True, ['o']),
#  (False, ['r', 'p']),
#  (True, ['i', 'o']),
#  (False, ['n'])]
p_output = []
# Now, we go over each group and do the encoding for the vowels.
for is_vowel_group, group_chars in s_groups:
p_output.extend(group_chars) # Add these chars to the output
if is_vowel_group: # Special treatment for vowel groups
p_output.append("p")
p_output.extend(c.lower() for c in group_chars)
return "".join(p_output)

我添加了一个列表推导来定义s_groups,向您展示它是如何工作的。您可以跳过列表推导,直接迭代for is_vowel_group, group_chars in itertools.groupby(s, lambda c: c.lower() in vowels)


现在,为了解码这个,我们可以反向做类似的事情,但这次手动进行分组,因为我们需要以不同的方式处理ps,当它们处于元音组的中间时。

我建议你不要修改字符串,因为你在它上面迭代。充其量,您将编写一些难以理解的代码。在最坏的情况下,您将出现bug,因为循环将尝试迭代比实际存在的更多的索引。

同样,您遍历1..len(p),然后尝试访问p[i+1]。在最后一次迭代中,这将抛出一个IndexError。因为你想把重复的元音算作一个组,所以这行不通。您必须将元音和非元音分开分组,然后将它们连接成单个字符串。

def p_decode(p):
vowels = {'a', 'e', 'i', 'o', 'u'}
p_groups = []
current_group = None
for c in p:
if current_group is not None:
# If the 'vowelness' of the current group is the same as this character
# or ( the current group is a vowel group 
#      and the current character is a 'p'
#      and the current group doesn't contain a 'p' already )
if (c.lower() in vowels) == current_group[0] or 
( current_group[0] and 
c.lower() == 'p' and 
'p' not in current_group[1]):      
current_group[1].append(c) # Add c to the current group
else:
current_group = None # Reset the current group to None so you can make it later
if current_group is None:
current_group = (c.lower() in vowels, [c]) # Make the current group
p_groups.append(current_group) # Append it to the list
# For scorpion => scoporpiopion
# p_groups looks like this:
# [(False, ['s', 'c']), 
#  (True, ['o', 'p', 'o']), 
#  (False, ['r', 'p']), 
#  (True, ['i', 'o', 'p', 'i', 'o']), 
#  (False, ['n'])]
p_output = []
for is_vowel_group, group_chars in p_groups:
if is_vowel_group:
h1 = group_chars[:len(group_chars)//2] # First half of the group
h2 = group_chars[-len(group_chars)//2+1:] # Second half of the group, excluding the p
# Add the first half to the output
p_output.extend(h1)
if h1 != h2:
# The second half of this group is not repeated characters
# so something in the input was wrong!
raise ValueError(f"Invalid input '{p}' to p_decode(): vowels before and after 'p' are not the same in group '{''.join(group_chars)}'")
else:
# Add all chars in non-vowel groups to the output
p_output.extend(group_chars)

return "".join(p_output)

现在,我们有:

words = ["An elephant", "scorpion", "boat", "boot", "Hello World", "stupid"]
for w in words:
p = p_encode(w)
d = p_decode(p)
print(w, p, d, sep=" | ")

这给了(美化我):

<表类>词编码解码一只大象一只大象一只大象蝎子scoporpiopion蝎子船boapoat船boopoot启动Hello Worldhellopo WorldHello World愚蠢stupupipid愚蠢

最新更新