Wie zähle ich die Buchstaben in Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch?
print(len('Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'))
Sagt 58
Wenn es so einfach wäre, würde ich dich nicht fragen, oder?!
Wikipedia sagt ( https://en.wikipedia.org/wiki/Llanfairpwllgwyngyll#Placename_and_toponymy )
Die lange Form des Namens ist mit 58 Zeichen der längste Ortsname im Vereinigten Königreich und einer der längsten der Welt (51 "Buchstaben", da "ch" und "ll" Digraphen sind und in der als einzelne Buchstaben behandelt werden Walisische Sprache).
Also möchte ich das zählen und die Antwort 51 erhalten.
Alles klar.
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
Ja, aber das ist Betrug, natürlich möchte ich das Wort als Eingabe verwenden, nicht die Liste.
Wikipedia sagt auch, dass die Digraphen auf Walisisch ch, dd, ff, ng, ll, ph, rh, th sind
https://en.wikipedia.org/wiki/Welsh_orthography#Digraphs
Also los geht's. Addieren wir die Länge und nehmen dann die Doppelzählung ab.
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)
Das bringt mich so weit
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
Es scheint, dass ich damals zu viele abgezogen habe. Ich soll 51 bekommen. Jetzt ist ein Problem, dass mit dem llll
es 3 ll
s gefunden und drei statt zwei abgenommen hat. Das muss also behoben werden. (Darf sich nicht überlappen.)
Und dann gibt es noch ein anderes Problem. Die ng
. Wikipedia hat nichts darüber gesagt, dass der Name einen Buchstaben "ng" enthält, aber er ist als einer der Digraphen auf der Seite aufgeführt, die ich oben zitiert habe.
Wikipedia gibt uns etwas mehr Ahnung hier: „zusätzliche Informationen benötigt werden , um eine echte digraph aus einer Aneinanderreihung von Buchstaben zu unterscheiden“ . Und es gibt das Beispiel von " llongyfarch ", wo das ng nur ein "Nebeneinander von Buchstaben" ist, und " llong ", wo es ein Digraph ist.
Es scheint also, dass 'Llanfairpwllgwy ng yllgogerychwyrndrobwllllantysiliogogogoch' eines dieser Wörter ist, bei denen das -ng- nur ein "Nebeneinander von Buchstaben" ist.
Und offensichtlich kann der Computer das auf keinen Fall wissen. Also muss ich ihm die "zusätzlichen Informationen" geben, über die Wikipedia spricht.
Wie auch immer, ich habe mich entschlossen, in einem Online-Wörterbuch http://geiriadur.ac.uk/gpc/gpc.html nachzuschlagen, und Sie können das sehen, wenn Sie llongyfarch nachschlagen (das Beispiel aus Wikipedia, das das "Nebeneinander von Buchstaben" enthält). es zeigt es mit einer vertikalen Linie zwischen dem n und dem g an, aber wenn Sie "llong" nachschlagen, tut es dies nicht.
Also habe ich beschlossen, dass wir die zusätzlichen Informationen bereitstellen müssen, indem wir ein |
wie in das Wörterbuch in die Eingabezeichenfolge einfügen, damit der Algorithmus weiß, dass das ng
Bit wirklich aus zwei Buchstaben besteht. Aber natürlich möchte ich nicht, dass das |
selbst als Brief gezählt wird.
Jetzt habe ich folgende Eingaben:
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)
und immer noch diese Liste von Digraphen:
['ch','dd','ff','ng','ll','ph','rh','th']
und die Regeln werden sein:
Fall ignorieren
Wenn Sie einen Digraphen sehen, zählen Sie ihn als 1
Arbeit von links nach rechts , so dass
llll
istll
+ll
nichtl
+ll
+l
Wenn Sie sehen, dass Sie
|
es nicht zählen, aber Sie es nicht vollständig ignorieren können, ist es dazung
da, kein Digraph mehr zu sein
und ich möchte, dass es als 51 zählt und es aus den richtigen Gründen tut, nicht nur als Zufall.
Jetzt bekomme ich 51, aber es macht es kaputt, weil es das |
als einen Buchstaben zählt (1 zu hoch), und dann nimmt es einen zu viel mit dem llll
(1 zu niedrig) ab - FEHLER ABBRECHEN
Es wird llong
richtig (3).
Es wird llon|gyfarch
falsch (10) - |
wieder zählen
Wie kann ich es richtig beheben?
count=count-1
hinzufügenindex=index+1
, um den nächsten Buchstaben zu überspringen?"ch dd ff ng ll ph rh th |".Split().ToList().ForEach(a => sb.Replace(a, a == "|" ? ".": "")); //sb is a stringbuilder
- ersetzen Sie einfach jeden der Digraphen durch ein Zeichen, das nicht in der Zeichenfolge vorkommt, und ersetzen Sie das Zeichen schließlich durch|
nichts. Die resultierende Länge ist Ihre Zeichenfolge. Kein Python-Entwickler, aber der gleiche Prozess sollte funktionieren, die Doppel durch ein Einzel zu ersetzen.Antworten:
Wie viele Probleme mit Strings kann dies mit einem regulären Ausdruck auf einfache Weise geschehen.
>>> word = 'Llanfairpwllgwyn|gyllgogerychwyrndrobwllllantysiliogogogoch' >>> import re >>> pattern = re.compile(r'ch|dd|ff|ng|ll|ph|rh|th|[^\W\d_]', flags=re.IGNORECASE) >>> len(pattern.findall(word)) 51
Die Zeichenklasse
[^\W\d_]
(von hier aus ) stimmt mit Wortzeichen überein, die keine Ziffern oder Unterstriche sind, dh Buchstaben, einschließlich solcher mit diakritischen Zeichen.quelle
pattern = re.compile(r'ch|dd|ff|ll|ph|rh|th|[a-z]|(ng^yf)', flags=re.IGNORECASE)
(ng^yf)
? Kann es jemals mit etwas übereinstimmen, wenn^
dies den Beginn der Zeichenfolge bedeutet?Sie können die Länge ermitteln, indem Sie alle Doppelbuchstaben durch ein
.
(oder ein anderes Zeichen,?
das in Ordnung ist) ersetzen und die Länge der resultierenden Zeichenfolge messen (die Menge von subtrahieren|
):def get_length(name): name = name.lower() doubles = ['ch', 'dd', 'ff', 'ng', 'll', 'ph', 'rh', 'th'] for double in doubles: name = name.replace(double, '.') return len(name) - name.count('|') name = 'Llanfairpwllgwyn|gyllgogerychwyrndrobwllllantysiliogogogoch' print(get_length(name)) >>> 51
quelle
Wenn Sie alle Buchstaben gesehen haben, endet die Schleife und Sie fügen alle Zählungen im Diktat hinzu.
Hier ist mein Code, er funktioniert anhand Ihrer drei Beispiele:
from collections import defaultdict digraphs=['ch','dd','ff','ng','ll','ph','rh','th'] breakchars=['|'] def welshcount(word): word = word.lower() index = 0 counts = defaultdict(int) # keys start at 0 if not already present while index < len(word): if word[index:index+2] in digraphs: counts[word[index:index+2]] += 1 index += 1 elif word[index] in breakchars: pass # in case you want to do something here later else: # plain old letter counts[word[index]] += 1 index += 1 return sum(counts.values()) word1='llong' #ANSWER NEEDS TO BE 3 (ll o ng) word2='llon|gyfarch' #ANSWER NEEDS TO BE 9 (ll o n g y f a r ch) word3='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) print(welshcount(word1)) print(welshcount(word2)) print(welshcount(word3))
quelle
Sie können ein kombinierendes Grapheme Joiner-Zeichen (+ u034F) verwenden, um die Buchstaben zu verbinden. Nehmen Sie dann die Anzahl Ihrer Zeichen und entfernen Sie die Anzahl dieser Joiner * 2.
http://www.comisiynyddygymraeg.cymru/English/Part%203/10%20Locales%20alphabets%20and%20character%20sets/10.2%20Alphabets/Pages/10-2-4-Combining-Grapheme-Joiner.aspx
Der walisische Sprachkommissar spricht das Problem auch hier an: http://www.comisiynyddygymraeg.cymru/English/Part%203/10%20Locales%20alphabets%20and%20character%20sets/10.2%20Alphabets/Pages/10-2-1- Character-vs - letter-count.aspx
quelle