音节化英语单词-种


11

您的任务是编写一个程序,该程序通过用连字符将单词分隔成一串文字。那将是很多工作,所以您想跳过一些部分,主要是因为您不想拥有完美算法所需的发音表。您还希望使它尽可能短(因此难以理解和难以维护),以作为为此任务分配的报仇。

您有两种选择:

  • 编写一个程序,该程序从STDIN中获取字符串并将结果输出到STDOUT。
  • 编写一个将字符串作为单个参数并返回结果的函数。

规格

  • 在这种情况下,字符串表示您选择的语言中的任何类似字符串的构造(字节数组,字符数组,字符串...)。
  • 元音是 a, e, i, o, u
  • 给定的字符串包含1 <= n <= 10单词,每个单词之间的长度都包括1 - 30字符在内。.您的输出应为带连字符的单词。
  • 所有字母均为小写,单词始终用空格分隔。因此,输入由字符组成[a-z ]
  • 按重要性顺序应用规则。
  • 划分单词时,请从单词的右半部分重新开始。

音节化规则,按重要性排序

两个连续的相同元音算一个(即feet只有一个元音,但beatfinding有两个)。每个音节正好有一个元音,因此每个元音都有一个音节。

  1. 如果整个单词只有四个字母,请原样返回。(将其跳过其余的单词)
  2. 如果单词只有一个元音,请原样返回单词。
  3. 如果单词有两个连续的元音,则将它们分开(即 diaspora -> di-as-po-ra
  4. 当两个或多个元音之间有两个或多个辅音(相同或不同)时,请在第一个辅音(即sis-ter)之后分割,除非辅音部分是ck,在这种情况下,请在其后分割单词。(即nickel -> nick-el
  5. 当a y在两个元音之间时,将其后的单词除(例如paying -> pay-ing)。
  6. 当一个辅音介于两个元音(相同或不同)之间时,请在辅音之前分开(即 dra-gon
  7. 如果无法进行除法,请返回原样。

我选择这些规则是因为它们可以递归地应用而不会出现问题,并且不需要发音表。因此,它们是不准确的,例如规则#5通常是不正确的。在一般情况下,是这样。

In:  hello world
Out: hel-lo world

In:  have a nice day
Out: have a nice day

In:  pour some nickel and xenon there
Out: pour some nick-el and xe-non the-re

你确定x-e-non吗?规则4的参考?
约翰·德沃夏克

@JanDvorak“当一个单词被分割时,请从单词的右半部分重新开始。”,然后是规则6。
seequ 2014年

我的意思是,规则4不应该只在音节之间分割吗?
约翰·德沃夏克

1
规则1处理四个字母词。少于四个字母的单词呢?例如lua
Digital Trauma 2014年

1
@DigitalTrauma他们通常会受到起诉,但很少有两个音节。
seequ 2014年

Answers:


6

Ruby,144个字节

如果我们追求难以维护,那么单个巨型正则表达式呢?

puts gets.split.map {|w| w.scan(/(^.{4}$|[^aeiou]*([aeiou])\2?((?=[^aeiouy]?[aeiou])|ck|[^aeiou]((?=.*[aeiou])|.*$)|$))/).map(&:first)*'-'}*' '

一些输出:

echo "hello world" | ruby syllable.rb
hel-lo world

echo "have a nice day" | ruby syllable.rb
have a nice day

echo "pour some nickel and xenon in there" | ruby syllable.rb
pour some nick-el and xe-non in the-re

echo "diaspora dragon paying sister hemlock happy quicksilver" | ruby syllable.rb
di-as-po-ra dra-gon pay-ing sis-ter hem-lock happy qu-ick-sil-ver

8

卢阿(292)

Lua可能不是最好的语言,但是它可以工作。它几乎像所问的问题一样流动。规则主要是按照顺序进行一些优化的:跳过#2(除非在开头有一个带有“ ck”的元音单词,否则将不需要),并且在其余#之前先通过ck和y规则4和#6,它们结合在一起。由于单词中的某些元音需要被捕获两次(在一个连字符之后和在另一个连字符之前),因此该搜索执行两次。

i=io.read()v="([aeiou])"for s in i:gfind("%l+ ?")do
if s:len()~=4 then
s=s:gsub(v..v,function(x,y)if x==y then return x..y;end;return x.."-"..y;end)s=s:gsub("ck"..v,"ck-%1")s=s:gsub(v.."y"..v,"%1y-%2")for b=1,2 do
s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")end
end
io.write(s)end

不打高尔夫球

function checkEquals(x,y)
    if x==y then 
        return x..y
    end
    return x.."-"..y
end
i=io.read()
v="([aeiou])"
for s in i:gfind("%l+ ?") do
    if s:len()~=4 then
        s=s:gsub(v..v,checkEquals)
        s=s:gsub("ck"..v,"ck-%1")
        s=s:gsub(v.."y"..v,"%1y-%2")
        for b=1,2 do
            s=s:gsub(v.."([^aeiou\-]?)([^aeiou\-]+)"..v,"%1%2-%3%4")
        end
    end
    io.write(s)
end

在此处进行测试:http//ideone.com/g57TzA


我没有红宝石,但确实不错。
seequ 2014年

4

Bash + coreultils,173个字节

我想我拥有所有最新的规则更改:

v=aeiou
r="[$v])/\1-\2/g"
s=s/\([$v]
e="$s[^$v-])([^$v-]+$r
"
tr \  \\n|sed -r "/^([a-z]{4}|[^$v]*[$v][^$v]*)$/bx
$s)($r
${s}ck)($r
$e$e${s}y)($r
$s)([^$v-]$r
:x"|tr \\n \ 

请注意,最后一行的最后一个字符是(空格)。

我认为这足以满足“无法阅读和无法维护” ;-)

接受来自STDIN的输入。

多为正则表达式直接替换。sed表达式的第一行与规则1和2匹配,然后简单地跳到:x表达式末尾的标签。

tr开始和管道的S端让文字换行分隔,所以他们更容易sed对付。我希望这样做,并且所有人都能sed回答,但是这种方式越来越简单。

例:

$ ./sylabify.sh <<< "diaspora nickel sister dragon hello world have a nice day pour some nickel and xenon there paying tricks quicksilver"
di-as-po-ra nick-el sis-ter dra-gon hel-lo world have a nice day pour some nick-el and xe-non the-re pay-ing tricks qu-ic-ksil-ver $ 

恩,我一直忘记规则3的修改。没关系。
Seequ 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.