【问题标题】:Sequence of vowels count元音计数序列
【发布时间】:2011-05-05 04:25:22
【问题描述】:

这不是作业题,是备考题。

我应该定义一个函数syllables(word) 来计算 一个词的方式如下:

• 元音的最大序列是一个音节;

• 词尾 e 不是音节(或者它是一部分的元音序列 的)。

我不必处理任何特殊情况,例如最后一个 e 在 单音节词(例如,“be”或“bee”)。

>>> syllables(’honour’)
2
>>> syllables(’decode’)
2
>>> syllables(’oiseau’)
2

我应该在这里使用正则表达式还是只列出理解?

【问题讨论】:

  • 什么是“元音的最大序列”?
  • 抱歉,我们不会为您制作单独的[examp-preparaton] 标签
  • “单词中的最后一个 e 不是一个音节(或它所属的元音序列)”。意味着“toe”没有音节,还是限制只是意味着最后的e不影响单词的音节数?
  • @SilentGhost 我不想为这个问题添加任何单独的标签,我只是想让人们知道解决方案代码是可取的,因为这不是人们通常给出建议而不是答案的作业。 @jball - 限制只是意味着最后的 e 不会影响单词的音节数。 @Matt Ball - 元音序列是两个或更多元音

标签: python regex nlp


【解决方案1】:

我发现这个问题的正则表达式很自然。 (我认为非正则表达式的答案需要更多的编码。我使用两种字符串方法,'lower' 和 'endswith' 使答案更清晰。)

import re
def syllables(word):
    word = word.lower()
    if word.endswith('e'):
        word = word[:-1]
    count = len(re.findall('[aeiou]+', word))
    return count

for word in ('honour', 'decode', 'decodes', 'oiseau', 'pie'):
    print word, syllables(word)

哪些打印:

honour 2
decode 2
decodes 3
oiseau 2
pie 1

请注意,“decodes”比“decode”多一个音节(这很奇怪,但符合您的定义)。

问题。这对你有什么帮助?学习问题的重点不是你自己解决吗?通过在您的问题中发布失败的尝试,您将来可能会获得更多好处,因此您可以准确了解自己的不足之处。

【讨论】:

  • @novalis。由于不想处理特殊情况的问题中的简单定义,我没有包括“y”。我认为 'y' 是一种特殊情况,因为它有时是元音,有时不是。但是,如果提问者希望 'y' 成为元音,请在正则表达式中插入 'y'。
  • @novalis 这是另一个难点:'Maya'
  • 我知道自己研究一个问题会更有效率……但不是这个。感谢您的解决方案。
【解决方案2】:

使用正则表达式 - 大多数语言都会让您计算字符串中正则表达式的匹配次数。

然后通过检查最右边的匹配组来对终端-e 进行特殊处理。

【讨论】:

  • 你可能会在最后的 e 中加入一些负面的前瞻或其他东西。
  • 你最好不要试图将 final-e 处理强制到同一个正则表达式中。在执行计数之前,只需删除任何以 'e' 结尾且带有 re.sub 的最终元音序列。
  • @Glenn Maynard,根据@Gusto 的评论,你只想修剪最后的'e',如果有的话,而不是最后的元音序列。令人困惑的规格,我知道。
【解决方案3】:

我认为正则表达式在这里不是正确的解决方案。

把每个字符串都当作一个列表来写似乎很简单。

【讨论】:

  • 取决于“最终 e”限制是什么,似乎正则表达式是最简单的解决方案。
  • 我想这取决于你如何定义“最微不足道的”
  • 为它想出一个 4-state DFA 并不难,我还没有尝试想出一个更小的 DFA。给定三种符号类型(元音除了 e、e、非元音),正则表达式基本上是自己写的。
  • 呃,刚刚写出来——应该是三态 DFA。
  • 我也是这样做的,你是对的,正则表达式很简单,如果你不关心有时 y 和 w。
【解决方案4】:

一些提示:

[abc] 匹配 abc

在正则表达式标记之后的+ 允许标记匹配一次或多次

$ 匹配字符串的结尾。

(?<=x) 仅当前一个字符是 x 时才匹配当前位置。

(?!x) 仅在下一个字符不是x 时才匹配当前位置。

编辑:

我刚刚看到您的评论,由于这不是家庭作业,因此需要实际的代码。 那么:

[aeiou]+(?!(?<=e)$)

如果您根本不想计算以e 结尾的最终元音序列(如tongue 中的utoe 中的o),请使用

[aeiou]+(?=[^aeiou])|[aeiou]*[aiou]$

如果您阅读上面的说明,我相信您将能够弄清楚它是如何工作的。

【讨论】:

  • 该表达式匹配 'tongue' 中的最后 'u',我认为这是正确的,但问题不是:“单词中的结尾 e 不是音节(或它的元音序列)是)"的一部分。
  • 是的,我还在等待 Gusto 回答 jball 的问题...可能只是编辑替代...
  • 他在长评论中包含了我的问题的答案,“限制只是意味着最后的 e 不会影响单词的音节数。”所以你的解决方案对我来说是正确的。
  • @jball:啊,谢谢,我没注意到。好吧,太晚了,我已经写了一个新的附加解决方案:)
【解决方案5】:

这是一个没有正则表达式的答案。我的真实答案(也已发布)使用正则表达式。未经测试的代码:

def syllables(word):
    word = word.lower()
    if word.endswith('e'):
        word = word[:-1]
    vowels = 'aeiou'
    in_vowel_group = False
    vowel_groups = 0
    for letter in word:
        if letter in vowels:
            if not in_vowel_group:
                in_vowel_group = True
                vowel_groups += 1
        else:
            in_vowel_group = False
    return vowel_groups

【讨论】:

    【解决方案6】:

    两种方式都有效。你自己说是为了备考。使用将要参加考试的任何一个。如果他们都在考试中,请使用您需要更多练习的。请记住:

    有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 ~杰米·扎温斯基

    所以在我看来,除非你需要练习,否则不要使用正则表达式。

    【讨论】:

    • 除了这种情况(可能)正是正则表达式的优点。当正则表达式是您工具箱中的唯一工具,并且您尝试使用众所周知的锤子来驱动螺钉时,就会出现问题。
    • @jball 太真实了。这就是为什么不使用正则表达式只是我的意见:)
    • 我建议使用您最熟悉的那个。如果您没有很多经验,正则表达式可能很难调试,但它们可以提供最简单的解决方案。另一方面,列表理解可能是最容易实现的,但解决方案可能很混乱。
    【解决方案7】:

    正则表达式太复杂了,列表推导可能不够健壮。您可能可以使用像PyParsing 这样的语法词法分析器轻松解决这个问题。试一试!

    【讨论】:

    • ...语法词法分析器对于考试问题来说太复杂了。我看不出正则表达式有什么问题。
    【解决方案8】:

    使用匹配 a、e、i、o 或 u 的正则表达式,将字符串转换为列表,然后遍历列表... 1 代表第一个真,1 代表下一个假,2 代表下一个真,2对于下一个 false 等。

    要处理最后一个字母在辅音后是“e”的情况(如 ate),只需在开始之前检查单词的最后两个字母。如果它们与该模式匹配,则截断最后的 e 并正常处理。

    【讨论】:

      【解决方案9】:

      此模式适用于您的定义:

      (?!e$)([aeiouy]+)
      

      只计算它发生了多少次。

      【讨论】:

        猜你喜欢
        • 2020-03-24
        • 2013-08-09
        • 2012-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-07
        相关资源
        最近更新 更多