我如何计算Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch中的字母数量?
print(len('Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'))
说58
如果那么容易,我就不会问你了,是吧?!
维基百科说(https://en.wikipedia.org/wiki/Llanfairpwllgwyngyll#Placename_and_toponymy)
该名称的长格式是英国最长的地名之一,在世界上也是最长的之一,共58个字符(51个“字母”,因为“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个“ll”,而不是两个,因此需要修复。(不能重叠。)
然后还有另一个问题。“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) - 又一次计算了 |
我该如何以正确的方式修复它?
count=count-1
之后,你能否添加index=index+1
来跳过下一个字母? - rhavelka"ch dd ff ng ll ph rh th |".Split().ToList().ForEach(a => sb.Replace(a, a == "|" ? ".": "")); //sb is a stringbuilder
- 只需将每个双字母替换为字符串中不存在的字符,最后将|
替换为空即可得到字符串长度。虽然我不是Python开发人员,但同样的过程应该也适用于Python,即将双字母替换为单个字符。 - Caius Jard