第85回【Python】英小文字の出現率、文字列の出現率

※ 第 85 回を作っていたのに、下書きで残っていました。順番前後しています。
現在取り組んでいるのは、paiza ラーニング問題集「データセット選択メニュー」になります。

はじめに

猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。

Python をゼロから勉強してみよう、のコーナー 85 回目です。

提出を求められる書類は出来る限り速やかに対応することを心掛けています。80 %の出来で 3 日前に提出すれば、修正箇所を認識合わせしたうえで、修正する時間を作ることができます。何度か繰り返して締め切り日までに 100 %にすれば良いという考え方です。

それでは、今日も頑張ってみようと思います。

英小文字の出現率

長さ N の文字列 S が与えられます。S に含まれている各文字の出現回数をそれぞれ求め、「a」の出現回数、「b」の出現回数、…、「z」の出現回数をこの順に半角スペース区切りで1行に出力してください。

N
S

すべてのテストケースにおいて、以下の条件をみたします。

・ 1 ≦ N ≦ 100
・ S は英小文字「a」,「b」, … ,「z」からなる長さ N の文字列


入力例

13
aaabbbccdddde

出力例

3 3 2 4 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

今回は、最初から辞書型で作れば OK かな?

Python
N = int(input())
S = input()
dic = { chr(x):0 for x in range(ord('a'),ord('z')+1) }
for s in S:
    dic[s] += 1
print(' '.join(map(str,dic.values())))
VBA
N = Cells(1, 1)
a = Cells(2, 1)
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
For i = Asc("a") To Asc("z")
    dic.Add Chr(i), 0
Next
For i = 1 To Len(a)
    dic.Item(Mid(a, i, 1)) = dic.Item(Mid(a, i, 1)) + 1
Next
For Each v In dic
    Debug.Print dic(v);
Next

文字列の出現率

文字列が N 個与えられます。各文字列の出現回数を文字列の辞書順に出力してください。

N
S_1
S_2
...
S_N

すべてのテストケースにおいて、以下の条件をみたします。

・ 1 ≦ N ≦ 100
・ S_i は英小文字「a」,「b」, … ,「z」からなる1文字以上3文字以下の文字列 (1 ≦ i ≦ N)


入力例

5
bcd
abc
bcd
bcd
bcd

出力例

abc 1
bcd 4

文字列の辞書順というところに注意。あとは、先ほどと変わらない。defaultdict を覚えてからは、in 演算子で存在確認をしていなかったから、最初戸惑ってしまった。

Python
N = int(input())
dic = {}
for _ in range(N):
    S = input()
    if S in dic:
        dic[S] += 1
    else:
        dic[S] = 1
for k,v in sorted(dic.items()):
    print(k,v)
VBA
Private Sub data_structure__dict_step3()

    N = Cells(1, 1)
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    For i = 1 To N
        S = Cells(i + 1, 1)
        If dic.exists(S) Then
            dic.Item(S) = dic.Item(S) + 1
        Else
            dic.Add S, 1
        End If
    Next
    arrKeys = dic.keys
    Dim arrList()
    ReDim arrList(dic.Count - 1, 1)
    For i = LBound(arrKeys) To UBound(arrKeys)
        arrList(i, 0) = arrKeys(i)
        arrList(i, 1) = dic(arrKeys(i))
    Next
    Call QuickSort(arrList, LBound(arrList, 1), UBound(arrList, 1))
    dic.RemoveAll
    For i = LBound(arrList) To UBound(arrList)
        dic.Add arrList(i, 0), arrList(i, 1)
    Next
    arrKeys = dic.keys
    For Each v In dic
        Debug.Print v & " " & dic.Item(v)
    Next

End Sub
Private Sub QuickSort(ByRef arrList() As Variant, ByVal minIDX As Long, ByVal maxIDX As Long)
 
    Dim valMEDIAN As Variant
    Dim arrTEMP() As Variant
    Dim i As Long
    Dim j As Long
     
    'ソート範囲の上下限を設定
    i = minIDX
    j = maxIDX
     
    '基準値としてインデックスの中央値のデータを使用します。
    valMEDIAN = arrList(Int((minIDX + maxIDX) / 2), 0)
 
    Do
        'インデックスの小さい方から値を比較していく
        Do While StrComp(arrList(i, 0), valMEDIAN) < 0
            i = i + 1
        Loop
         
        'インデックスの大きい方から値を比較していく
        Do While StrComp(arrList(j, 0), valMEDIAN) > 0
            j = j - 1
        Loop
         
        'インデックスが逆転したらループ抜け
        If i >= j Then Exit Do
         
        '配列を定義
        ReDim arrTEMP(0, 1)
         
        '配列内のデータの入れ替え1
        arrTEMP(0, 0) = arrList(i, 0)
        arrList(i, 0) = arrList(j, 0)
        arrList(j, 0) = arrTEMP(0, 0)
         
        '配列内のデータの入れ替え2
        arrTEMP(0, 1) = arrList(i, 1)
        arrList(i, 1) = arrList(j, 1)
        arrList(j, 1) = arrTEMP(0, 1)
         
        '配列の初期化
        Erase arrTEMP
         
        'インデックスの加減算
        i = i + 1
        j = j - 1
    Loop
     
    '再帰でソートが完了するまで繰り返し
    If (minIDX < i - 1) Then Call QuickSort(arrList, minIDX, i - 1)
    If (maxIDX > j + 1) Then Call QuickSort(arrList, j + 1, maxIDX)
     
End Sub

クイックソートについては、こちらを利用させて頂きました。ありがとうございます。

最後に

VBA の連想配列で Key を基準に並べ替える方法は、関数を自分で作るか、.NET Framework の ArrayList クラスを利用するかになるらしい。.NET Framework は環境によって使えないかもしれないし、ということで、人様の関数を利用させていただいた。ありがとうございます。

ワークシートに入れちゃえば簡単にソートできるのだけれど、それが良いかどうかは・・・。なかなか難しい。

引き続き、よろしくお願いいたします!

PythonPython,paiza,学習

Posted by LeoSaki