【发布时间】:2020-12-11 04:34:33
【问题描述】:
如何计算 Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch 中的字母?
print(len('Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'))
说 58
如果这么简单,我就不会问你了,现在可以吗?!
维基百科说 (https://en.wikipedia.org/wiki/Llanfairpwllgwyngyll#Placename_and_toponymy)
名字的长形式是美国最长的地名 王国和世界上最长的王国之一,有 58 个字符 (51 "letters" 因为 "ch" 和 "ll" 是有向图,并被视为单个 威尔士语字母)。
所以我想数一下,得到答案 51。
好啊。
print(len(['Ll','a','n','f','a','i','r','p','w','ll','g','w','y','n','g','y','ll','g','o','g','e','r','y','ch','w','y','r','n','d','r','o','b','w','ll','ll','a','n','t','y','s','i','l','i','o','g','o','g','o','g','o','ch']))
51
是的,但那是作弊,显然我想使用单词作为输入,而不是列表。
维基百科还说威尔士语的二合字母是ch, dd, ff, ng, ll, ph, rh, th
https://en.wikipedia.org/wiki/Welsh_orthography#Digraphs
所以我们走吧。让我们把长度加起来,然后去掉重复计算。
word='Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'
count=len(word)
print('starting with count of',count)
for index in range(len(word)-1):
substring=word[index]+word[index+1]
if substring.lower() in ['ch','dd','ff','ng','ll','ph','rh','th']:
print('taking off double counting of',substring)
count=count-1
print(count)
这让我走到了这一步
starting with count of 58
taking off double counting of Ll
taking off double counting of ll
taking off double counting of ng
taking off double counting of ll
taking off double counting of ch
taking off double counting of ll
taking off double counting of ll
taking off double counting of ll
taking off double counting of ch
49
看来我已经减去了太多。我应该得到 51。现在的一个问题是,llll 找到了 3 个lls,并且删除了三个而不是两个。所以这需要修复。 (不得重叠。)
然后还有另一个问题。 ng。维基百科没有说名字中有一个字母“ng”,但它被列为我上面引用的页面上的二合字母之一。
维基百科在这里为我们提供了更多线索:“可能需要额外的信息来区分真正的二合字母和并列的字母”。它给出了“llongyfarch”的例子,其中 ng 只是“字母的并置”,而“llong”则是一个有向图。
因此,'Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch' 似乎是其中一个 -ng- 只是“字母并置”的词之一。
显然计算机不可能知道这一点。所以我将不得不给它提供维基百科所说的“附加信息”。
所以无论如何,我决定查看在线词典http://geiriadur.ac.uk/gpc/gpc.html,如果您查找 llongyfarch(维基百科中的“字母并列”示例),它会显示在 n 和 g 之间有一条垂直线,但如果您查找“llong”,则它不会这样做。
所以我已经决定好了,我们需要做的是通过在输入字符串中像在字典中一样输入 | 来提供附加信息,以便算法知道 ng 位确实是两个字母。但显然我不希望 | 本身被算作一个字母。
所以现在我有这些输入:
word='llong'
ANSWER NEEDS TO BE 3 (ll o ng)
word='llon|gyfarch'
ANSWER NEEDS TO BE 9 (ll o n g y f a r ch)
word='Llanfairpwllgwyn|gyllgogerychwyrndrobwllllantysiliogogogoch'
ANSWER NEEDS TO BE 51 (Ll a n f a i r p w ll g w y n g y ll g o g e r y ch w y r n d r o b w ll ll a n t y s i l i o g o g o g o ch)
还有这个二合字母列表:
['ch','dd','ff','ng','ll','ph','rh','th']
规则如下:
-
忽略大小写
-
如果您看到一个有向图,则将其计为 1
-
从左到右工作,使
llll是ll+ll,而不是l+ll+l -
如果您看到
|不计其数,但您不能完全忽略它,它可以阻止ng成为有向图
我希望它算作 51 并出于正确的理由这样做,而不仅仅是侥幸。
现在我得到 51,但它是侥幸,因为它把 | 算作一个字母(1 太高),然后它用 llll 起飞太多了(1 太低) -错误取消
llong 正确 (3)。
llon|gyfarch 错误 (10) - 再次计算 |
我怎样才能以正确的方式解决它?
【问题讨论】:
-
既然您尝试测量的只是一个单词并且您知道该单词及其长度,为什么不创建一个常量字符串来包含该字符串,并创建一个常量 int 来包含字符串并完成它?不需要在代码中这样做,对吧?
-
我对python了解不多。完成
count=count-1之后,可以添加index=index+1跳过下一个字母吗? -
所以我对python不太了解,但我认为他们必须对字符串有一些文化概念?例如,在 .NET 中,您可以设置应用程序的文化,并以此为基础对某些字符进行不同的处理。除非这里的想法是您尝试自己从头开始实施,否则请忽略此评论。
-
如果是 C#,我可以提供
"ch dd ff ng ll ph rh th |".Split().ToList().ForEach(a => sb.Replace(a, a == "|" ? ".": "")); //sb is a stringbuilder- 只需将每个二合字母替换为字符串中未出现的字符,最后将|替换为空;结果长度是你的字符串。不是 python 开发人员,但应该使用相同的过程,用单个替换双打.. -
"th" 和 "sh" 是英语中的二合字母,但我从来没有遇到过从字形意义上考虑这些“单个字母”的人。您问的是如何计算“phonemes”,它以笨拙地映射到用字母书写的语言而臭名昭著。您已经确定的音节中断只是一种歧义。