ウェールズ語のテキストの文字を数える

Aug 21 2020

Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogochの文字を数えるにはどうすればよいですか?

print(len('Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch'))

58は言う

さて、それが簡単だったら、私はあなたに尋ねないでしょう、今私はそうしますか?!

ウィキペディアは言う(https://en.wikipedia.org/wiki/Llanfairpwllgwyngyll#Placename_and_toponymy)

名前の長い形式は、英国で最も長い地名であり、58文字で世界で最も長いものの1つです(「ch」と「ll」は有向グラフであるため、51の「文字」であり、ウェールズ語)。

だから私はそれを数えて答え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を取得することになっています。今1つの問題は、llllそれが3を見つけll、2つではなく3つを外したことです。したがって、これを修正する必要があります。(重複してはいけません。)

そして、別の問題があります。ng。ウィキペディアは、名前に「ng」という文字が含まれていることについては何も述べていませんが、上記で引用したページの有向グラフの1つとしてリストされています。

ウィキペディアはここでもう少し手がかりを与えてくれます:「本物の有向グラフと文字の並置を区別するために追加情報が必要になるかもしれません」。また、ngが単なる「文字の並置」である「llongyfarch」と、有向グラフである「llong」の例を示しています。

したがって、「Llanfairpwllgwy ng yllgogerychwyrndrobwllllantysiliogogogoch」は、-ng-が単なる「文字の並置」である単語の1つであるように思われます。

そして明らかに、コンピュータがそれを知る方法はありません。ですから、ウィキペディアが話している「追加情報」を提供する必要があります。

とにかく、私はオンライン辞書を調べることにしました http://geiriadur.ac.uk/gpc/gpc.htmlそして、あなたがルックアップする場合ていることがわかりますllongyfarch(「文字の並置を」持っているウィキペディアの例)、それはでそれを表示するのnとgの間の縦線が、あなたがルックアップする場合は、「LLONG」それはありませんこれを行う。

したがって、必要|なことは、辞書の場合と同じように入力文字列にを入力して追加情報を提供することです。これにより、アルゴリズムはngビットが実際には2文字であることを認識します。しかし、明らかに私は|それ自体が手紙として数えられることを望んでいません。

だから今私はこれらの入力を持っています:

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. ケースを無視する

  2. 有向グラフが表示された場合は、1として数えます

  3. 左から右そうに仕事llllll+ ll、ありませんl+ ll+l

  4. |あなたがそれを数えないのを見ても、それを完全に無視することができないなら、それはng有向グラフであるのをやめるためにそこにあります

そして私はそれを51として数え、それをまぐれにするだけでなく、正しい理由でそれを実行したいと思っています。

今私は51を取得していますが、それは|文字として数えているので(1が高すぎる)、それはそれを混乱させています、そしてそれはllll(1が低すぎる)で1つを取りすぎています-エラーキャンセル

順調に進んでいllongます(3)。

それはllon|gyfarch間違っています(10)-|もう一度数えます

どうすれば正しい方法で修正できますか?

回答

59 kaya3 Aug 21 2020 at 19:24

文字列に関する多くの問題と同様に、これは正規表現を使用して簡単な方法で実行できます。

>>> 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

文字クラス[^\W\d_](ここから)は、数字やアンダースコアではない単語文字、つまり発音区別符号付きの文字を含む文字と一致します。

20 Nathan Aug 21 2020 at 19:22

すべての二重文字を.(または他の文字で問題?なく実行できます)に置き換え、結果の文字列の長さを測定する(の量を差し引く|)ことで、長さを取得できます。

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
9 Carlos Aug 21 2020 at 19:18
  1. 文字列を1文字ずつステップスルーします
  2. インデックスnにいて、s [n:n + 2]が有向グラフである場合は、有向グラフをキーとして辞書を追加またはインクリメントし、インデックスも1ずつインクリメントして、2番目の有向グラフから開始しないようにします。キャラクター。有向グラフでない場合は、文字をdictに追加またはインクリメントして、次の文字に移動します。
  3. |が表示された場合 文字、数えないで、スキップしてください。
  4. そして、小文字にすることを忘れないでください。

すべての文字を確認したら、ループが終了し、すべてのカウントをdictに追加します。

これが私のコードです、それはあなたの3つの例で動作します:

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))
1 JamesRushford Sep 18 2020 at 10:14

Combining Grapheme Joiner(+ u034F)文字を使用して文字を結合し、文字数を取得して、これらの結合子の数を取り除くことができます* 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

ウェールズ語コミッショナーもここで問題に取り組んでいます: http://www.comisiynyddygymraeg.cymru/English/Part%203/10%20Locales%20alphabets%20and%20character%20sets/10.2%20Alphabets/Pages/10-2-1-Character-vs--letter-counts.aspx