【问题标题】:Optimize beginner python script about substring replacement优化关于子字符串替换的初学者python脚本
【发布时间】:2017-10-20 00:09:03
【问题描述】:

我正在给一个朋友辅导 python,我自己并不擅长。任务是编写一个脚本来反转一些编造的外星语言,在这些语言中,他们在添加字母“p”后重复每个元音序列。一些例子:

tomato -> topomapatopogroovy->groopoovybeautiful -> beaupeautipifupul

我们的目标是扭转这一局面。来自groopoovy -> groovy

因为它是荷兰语赋值,所以有一个例外:“ij”被视为元音。所以blijpij -> blij(我发现这让事情变得很复杂)

我的解决方案对我来说似乎相当庞大,我对更好、更优雅的解决方案感兴趣。由于这是一门编程入门课程,很遗憾,基础知识很关键。

    word = input()
    vowels = ('a', 'e', 'i', 'o', 'u')
    position = 0
    solution = ""
    while position < len(word):
        if word[position] == 'p':       # obviously, search for the letter 'p'
            add = 1                     # keep track of the sub string size
            group = ""
            while True:                 # loop to get consecutive vowels
                if word[position + add] in vowels:
                    group += word[position + add]
                    if word[position + add] == 'i' and word[position + add + 1] == 'j':   # recognize the "ij"
                        group += 'j'
                        add += 1
                    add += 1
                else:
                    break
                if position+add == len(word):       # stay within the bounds of the string
                    break
            add -= 1
            if word[position - add:position].lower() == group.lower() and group != "":
                position += add
            else:

                solution += 'p'
        else:
            solution += word[position]
        position += 1
    print(solution)

【问题讨论】:

    标签: python string char


    【解决方案1】:

    这个怎么样,对于一个介绍性的 Python 课程。 顶部有几个示例词;只需更改 cmets #.

    我不是在每一步都检查“p”,而是检查元音序列的开头。该序列将始终以“p”终止。这是您不想将字符附加到解决方案的唯一情况;相反,您想跳到元音序列的末尾。

    “ij”是元音这一事实不会产生特殊情况,因为“i”开始一个元音序列。

    word = "poopoo-poopoo"
    # word = "poopooh"
    # word = "hijipijinks"
    # word = "apapepe"
    # word = "copovfepefepe"
    vowels = ('a', 'e', 'i', 'o', 'u')
    position = 0
    solution = ""
    vowel_count = 0   # consecutive vowels
    while position < len(word):
        c = word[position]
        if vowel_count > 0:
            if c == 'p':
                position += vowel_count + 1
                vowel_count = 0
                continue
            vowel_count += 1
        else:
            if c in vowels:
                vowel_count = 1
        solution += c
        position += len(c)
    
    print(solution)
    

    【讨论】:

    • 这确实是我正在寻找的更优雅的解决方案。谢谢保罗。当c=='p' 时,它需要稍作调整来检查左右部分,否则像“cape”这样的词会被破坏。
    • 程序假定输入的单词是根据你的食谱格式化的,并且不会检查它的语法或拼写错误。你的版本也没有检查。 “cape”不是有效的输入。 “capapepe”有效且正确地给出结果“cape”。
    【解决方案2】:
    import re
    input_text = "tomato"
    encoded = re.sub('([aeiou]+)','\\1p\\1',input_text)
    print(encoded)
    decoded = re.sub('([aeiou]+)p\\1','\\1',encoded)
    print(decoded)
    

    应该这样做

    【讨论】:

    • 感谢您的快速回复。我也在考虑正则表达式,但不知道如何处理“ij”-is-a-vowel 部分。仍然想不出正则表达式的方法来做到这一点..
    • @FrankVermeulen 将 [aeiou] 更改为 (?:[aeiou]|ij)
    • 使用原始字符串,这样你就不需要加倍反斜杠了。
    • 完美!它甚至可以放在一行中:import re;print(re.sub(r'((?:[aeiou]|ij)+)p\1', r'\1', input()))
    猜你喜欢
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2022-11-16
    相关资源
    最近更新 更多