猜猜德语单词如何发音


37

介绍

与英语不同,德语被认为具有相当的音素书写系统。这意味着拼写和发音之间的对应关系很紧密。给定您不熟悉的任何单词,由于拼写系统,您仍然会知道如何发音。这意味着计算机应该能够正确执行此操作吗?

挑战

编写一个程序或函数,将代表德语单词的字符串作为输入,并以国际语音字母(IPA)打印或返回其发音。

我当然不会让您学习德语或完整的IPA。这个Wikipedia部分提供了您所需的几乎所有的德语到IPA规则,并且我已经编写了一个非高尔夫C#参考实现

在该链接还提供了一个名单的400个共同德语单词和他们的IPA发音(需要验证)。以该列表为例,如果输入为solltest,则正确的输出为ˈzɔltəst

参考实现添加了两个在Wikipedia部分中未提及的有用规则:假定单词重音位于第一个音节上(很有可能在德语中),并使用更好的试探法来确定字母“ e”何时表示schwa声音/ə/。它还对前缀执行特殊处理,但是并没有像我想的那样改善结果。

细节

要被视为有效条目,您的程序必须满足以下要求:

  • 您的IPA输出必须与参考单词列表中的400个单词中的至少300个完全匹配(参考实现正确获得333个)
  • 您的程序必须猜测任何可能是德语的单词。因此,我们有一项技术要求,这意味着对于任何与正则表达式匹配[a-zA-ZäÄöÖüÜ][a-zäöüß]*且具有至少一个元音(aeiouyäöü)的输入,您必须产生非空白输出,并且不能出错。
  • 程序必须是确定性的(在给定相同输入的情况下始终产生相同的输出)
  • 否则,将禁止出现标准漏洞(尤其是关于获取异地资源的漏洞

您可以做其他杂项:

  • 如果您必须在输出中包含前导和尾随空格
  • 在输出中使用任何先前存在的字符编码(我想不到除了Unicode可以正常工作以外的任何方法,但是如果可以的话,恭喜)
  • 假设输入采用某种规范化形式,例如Unicode规范化形式NFD,NFC等。例如,ä是写为单个字符还是基本字符+组合字符?
  • 使用标准输入和输出方法

评分和IPA字符

得分以字节为单位。请注意,德语字符和IPA字符均为UTF-8中的2个字节。同样,IPA字符U + 0327下方的反向组合键(̯)是Unicode组合字符,它本身就是2字节的UTF-8字符。这意味着类似ɐ̯的东西在UTF-8中算作4个字节。对于好奇的人,此符号表示元音不构成音节核(上一个则不然)。

另外,请注意这些IPA字符在某些字体中看起来像其他ASCII字符:ɡ,ɪ,ʏ,ː(标记为长元音),ˈ(音节在多音节单词中带有重音的标记)。

参考单词列表的创建方式

本部分是挑战所不需要的额外信息。

该单词列表是从该维基词典单词频率列表中获取的,由于大小写不同以及两个单词在英语维基词典中没有德语条目而删除了重复单词(哦和嘿)。IPA来自英国和德国的维基词典。在提供多种发音的地方,我选择了较为正式和标准的发音。如果不清楚,我选择最适合一般规则的规则。

我还必须标准化字母“ r”的发音方式。这封信的发音很大程度上取决于该地区,而维基词典在所选择的那封信上根本不一致。我觉得它趋向于以下:“ r”的发音是/ɐ̯/,后面是长元音,而后面没有元音,否则是ʁ。因此,我更改了所有它们以遵循该规则,除了/(f)ɛɐ̯/非常一致的ver-和er-前缀。同样,我将“ eu”标准化为/ɔʏ̯/。


16
Mathematica为此(#~WordData~"PhoneticForm"&)提供了内置功能,但仅适用于英语单词。
JungHwan Min

29
@JungHwanMin我阅读了您的评论,内容如下:立即心脏病发作,松了一口气。
DPenner1

1
我怎么知道“ gestern”的发音是“ GHES-tern”而不是“ ge-SHTERN”?“ bester”作为“ Best-er”而不是“ be-SHTER”?
Leaky Nun

@LeakyNun没有100%的算法,但是您的实现只需要获得75%。我的参考实现也弄错了这些词。
DPenner1

@LeakyNun好吧,您的程序也将能够处理德语方言,因此它功能更强大。
P. Siehr

Answers:


9

PHP,3311 2988 2916 2845 2759 2671 2667 2509 2484字节,传递301/400

<?$f=fopen(__FILE__,r);fseek($f,__COMPILER_HALT_OFFSET__);eval(strtr(stream_get_contents($f),[F=>'=>',M=>'==','&'=>'&&',H=>'function ',A_=>'array',G=>'if',4=>'for','|'=>'||','~'=>'))','%'=>str,7=>'=$',8=>'[]',9=>'!$','@'=>'count(','#'=>';$',5=>'return ',3=>':(']));__halt_compiler();define(J,[ieh,ah,aa,Ah,eh,ee,ie,ih,oh,oo,Oh,uh,Uh,au,eu,Au,ei,ai,ey,ay,a,e,i,o,u,A,O,U,y])#b7e=8;Hv($a){5in_A_($a,J);}Hn($a){5!v($a);}Hpronounce($w){global$b,$e#w=%tr(%tolower(%tr($w,[ßF1,ÄF2,äF2,ÖF0,öF0,ÜF6,üF6]~,[1FS,2FA,0FO,6FU])#W=8#L7w;while($L)4each(A__merge([tzsch,dsch,tsch,zsch,sch,chs,ch,ck,dt,ng,nk,pf,ph,qu,ss,th,tz,b,c,d,f,g,h,j,k,l,m,n,p,r,s,S,t,v,w,x,z],J)as$c){$l=%len($c);G(sub%($L,0,$l)M$c){$W87c#L=sub%($L,$l);break;}}$s=8#l=@$W);4($o7t7i=0#i<$l#i++){$c7W[$i]#p7i?$W[$i-1]:0#n7iM$l-1?0:$W[$i+1];G(9n|!(n($c)&$cM$n&n($W[$i+2]~)$s[$o]87c;G($p&((9n&v($c)&n($p~|(n($n)&v($W[$i+2]~~$s[++$o]=8;}$s[@$s)-1]|A__pop($s);4each($s as$z){$b87t#t+=@$z)#e87t;}$o=[sieFziQ,duFduQ,'die'FdiQ,derFdeQT,zuFtsuQ,wirFviQT,mirFmiQT,denFdeQn,dassFdas,erFeQT,soFzoQ,warFvaQT,fürFfyQT,jaFjaQ,wieFviQ,dirFdiQT,nurFnuQT,demFdeQm,ihnFiQn,auchFaUBx,ihrFiQT,daFdaQ,schonFʃoQn,wennFvEn,malFmaQl,gutFguQt,nachFnaQx,willFvIl,mussFmUs,habFhaQp,vorFfoQT,ihmFmiQm,tunFtuQn][$w]?:'';G($o)goto x#P7B7S7V7Z=0;@$s)>1&$o=[verFfET,daFda,geFgC][join($s[0])]#o&$P=1&A__shGt($s);(($P|@$s)M2)&$o.=W)|(@$s)>2&$d=1&$h=(int)@$s)/2)#w=A__merge(...$s);4each($w as$l){G(0<$S--)continue#n7w[$B+1]#p7w[$B-1]#f=''#Z+=in_A_($B,$b)#f7lMd&9n?t3$lMb&(9n|$nMt)?p3$lMg&(9n|$nMt)?((9n&$pMi)?K:k)3$lMc?(($nMA|$nMe|$nMi)?ts:k)3$lMch?(($pMa|$pMo|$pMu)?x:K)3$lMchs|$lMx?ks3$lMck?k3$lMdsch?dZ3$lMdt|$lMth?t3$lMph|$lMv?f39f&$lMg?g3$lMh?(v($n)?h:'')3$lMng?N3$lMnk?Nk3$lMqu?kv3$lMr?((!v($n)&9nMt)?T:R)3$lMsch?S3$lMss|$lMS?s3$lMtsch|$lMtzsch|$lMzsch?tS3$lMtz|$lMz?ts3$lMw?v3$lMs?(9p&($nMp|$nMt~?S3v($n)?z:s):$f~~~~~~~~~~)#U=0;G(v($l~{G(%len($l)>1)($f=[auFaUB,euFcYB,eiFaIB][$l])|$U=1;else{G(n($n)&((9w[$B+2]&$n!=n)|v($w[$B+2]~)$U=1;G($lMe){$U=9n?:$U;G(9w[$B+2]){G($nMr)($f=A)&$U=9S=1;G($nMm|$nMl)$f=C;}}elseG($nMch)$U=0;G(in_A_($B,$e~$U=0;}$f=($U|9Z)&9f?($l[0]MO?D3$l[0]MU?y3$l[0]MA?E:$l[0]~).Q39f?($lMe?((9n|(9w[$B+2]&($nMn|$nMs~)?C:E)3$lMA?E3$lMi?I3$lMo?c3$lMu?U3($lMU|$lMy)?Y:$l~~~:$f)#V++;}$f7f?:$l;G($d&$ZM$h)$f.=W#o.7f#B++;}G(%pos($o,W)M=false&$V>1)$o=W.$o;4(#j++<%len($o);)G($o[$j]M$o[$j+1])$o=sub%($o,0,$j).sub%($o,$j+1);x:5%tr($o,[SFʃ,ZFʒ,KFç,gFɡ,NFŋ,QF'ː',WFˈ,TFɐ̯,BF'̯',RFʁ,AFɐ,EFɛ,OFœ,IFɪ,YFʏ,UFʊ,cFɔ,CFə,DFø]);}

定义pronounce(string $word)

用法:

assert(
    pronounce('darüber') == "daˈʁyːbɐ"
);

注意事项:3个前缀和33个单词是硬编码的,并且某些代码已针对测试列表进行了适度的优化。

测试代码在这里,尽管它确实取决于此文件

去测试:

php test.php all

由三元陈述的眼泪提供动力。

编辑7:通过将预处理器写入程序中,压缩了约170个字节。因此,实际的程序(之后的所有内容__halt_compiler();)有点难以阅读。如果你想未处理程序,切换evalprint在第三条语句。


这实际上是2667个字节,而不是2671个字节(假定为UTF-8)
caird coinheringaahing
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.