第89回【Python】集合の結合

現在取り組んでいるのは、paiza ラーニング問題集「データセット選択メニュー」になります。

はじめに

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

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

「データセット選択メニュー」も今回で最後。問題集の中で「C ランク獲得」に分類されているものは、ほとんど終わりです。次回からは、C ランクを目指すためのメニューに挑戦する予定です。その前に「データセット選択メニュー」をしっかり終わらせます。

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

集合の結合

N 個の要素からなる数列 A, B が与えられます。A または B に含まれる値をすべて列挙し、重複を取り除いて昇順に出力してください。答えとなる数列 C を半角スペース区切りで1行に出力してください。

N
A_1 A_2 ... A_N
B_1 B_2 ... B_N

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

・ 入力はすべて整数
・ 1 ≦ N ≦ 100
・ 1 ≦ A_i, B_i ≦ 1,000,000,000 (1 ≦ i ≦ N)


入力例

3
1 2 3
3 4 5

出力例

1 2 3 4 5

重複を取り除くために利用するのは、Python の場合、set を使うのが一番簡単で速い。

Python
N = int(input())
A = [ int(x) for x in input().split() ]
B = [ int(x) for x in input().split() ]
C = set(A + B)
print(' '.join(map(str,sorted(C))))
VBA
Private Sub data_structure__set_boss()

    N = Cells(1, 1)
    a = Split(Cells(2, 1), " ")
    b = Split(Cells(3, 1), " ")
    Dim dic As Object
    Set dic = CreateObject("Scripting.Dictionary")
    Set dic = add_dic(dic, a)
    Set dic = add_dic(dic, b)
    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 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
Private Function add_dic(dic, x) As Object

    For i = 0 To UBound(x)
        If Not dic.exists(x(i)) Then
            dic.Add x(i), x(i)
        End If
    Next
    Set add_dic = dic

End Function

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

最後に

Python では 5 行で終わったコードが、VBA ではなかなかの大仕事になってしまいました。ちゃんと改行で終わっていないし、末尾に半角スペースがついているため、完全な正解とは判定されないかもしれません(判定されないです)。

VBA では、ワークシートという裏技(?)があるため、こんなに複雑なコードを書かなくてもなんとかなるものです。しかし、やり方を知っていれば、他の言語でも応用はいくらでも効きます。

次回からは「C ランクレベルアップメニュー」に挑戦しようと思います。ここまでやってきた内容を考えると、少し物足りないと思いますが、是非、お付き合いください。

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

PythonPython,paiza,学習

Posted by LeoSaki