需要帮助破解语言吗

2024-10-03 06:29:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我不知道你是否熟悉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)

这是我到目前为止的代码,除了我不知道如何使双元音听起来像蝎子(scoporpiopion)中的“io”外,它工作正常

此外,当一个句子以元音开头时,该代码对该元音不起作用。 例如,“Apan epelepephapant”在我的代码中变成了“Apan大象”

当字符串索引不以“.”结尾时,我的代码会崩溃,字符串索引超出界限。但每当我没有“.”的if时,它都会崩溃

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

编辑:为了澄清,就像在我的例子中一样,组合元音应该算作1个元音。蝎子将是Scoporpiopin而不是Scoporpiopon,船将是boapoat,靴子将是boopoot


Tags: 字符串代码语言forinputif国家单词
3条回答

既然@Kolmar已经给出了一个regex solution,我将添加一个没有正则表达式的

为了帮助思考这一点,我将首先向您展示我的解决方案,将常规字符串编码为p语言。在这种方法中,我使用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)


现在,对于解码EME>这,我们可以逆向地做一些类似的事情,但是这次手动分组,因为我们需要处理{{CD4}},当它们位于元音组的中间时。p>

我建议您在迭代字符串时不要修改它。充其量,您将编写一些难以理解的代码。在最坏的情况下,您将有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=" | ")

其中给出了(修饰矿):

^{tb1}$

此外,实际上编码不正确的单词(如"stupid")会抛出ValueError

>>> p_decode("stupid")

ValueError: Invalid input 'stupid' to p_decode(): vowels before and after 'p' are not the same in group 'upi'

可以使用正则表达式执行此操作:

import re

def decodePLanguage(p):
    return re.subn(r'([aeiou]+)p\1', 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]+)p\1'中,[aeiou]+部分匹配一行中的几个元音,并且\1确保在p之后有相同的组合

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

编辑:工作代码

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))

相关问题 更多 >