第155回【Python】数字のみの出力、昇順ソート出力、文字と整数の組のソート
現在取り組んでいるのは、paiza ラーニング問題集「B ランクレベルアップメニュー」になります。
はじめに
猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。
Python をゼロから勉強してみよう、のコーナー 155 回目です。
リモートの環境が整っていないなかでリモートを行うのは、長期的に見て愚策だと思っています。実際、リモートを行っている別部署は 3 年経過して状況が良いとは言えないと感じています。大金を投じて環境を整えるか、リモートを解除するか、そろそろ選択の時だと思うのだけれど。
それでは、今日も頑張ってみようと思います。
今回取り組む内容について
以下は、前回までに取り組んだ問題とまったく同じなので、飛ばします。
コードは数書いてナンボとかカッコつけたこと書いてましたが、あまりにも多いので挫折しました。
STEP: 1 インクリメント
数字のみの出力 (paizaランク D 相当)
1行目に行数を表す整数 n、続く n 行で m 個の「文字」と「整数」の組が空白区切りで入力されます。
n 個の整数だけをそのまま順に出力してください。
n
S_1 D_1
S_2 D_2
...
S_n D_n
期待する出力
n 個の整数を順に改行区切りで出力してください。
最後は改行し、余計な文字、空行を含んではいけません。
すべてのテストケースにおいて、以下の条件をみたします。
・1 ≦ n ≦ 10,000
・-10,000 ≦ D_i ≦ 10,000 (ただし、1 ≦i ≦ n)
・S_iは1つの半角英文字
入力例
4
S 1
F 2
E 5
Y 6
出力例
1
2
5
6
何がしたいのかはよくわからないが、「整数」だけを取り出す作業を行う。
Python
n = int(input())
for _ in range(n):
s,d = input().split()
print(int(d))
模範解答では、「整数」として出力していないのだけれど。print(d) だけ書くのは、問題の意図に合わない気がする。
VBA
Sub sort_asc_1()
N = Cells(1, 1)
For i = 1 To N
sd = Split(Cells(i + 1, 1), " ")
Debug.Print Val(sd(1))
Next
End Sub
昇順ソート出力 (paizaランク D 相当)
1行目で整数 n が与えられ、2行目で n 個の整数が与えられます。
n 個の整数を昇順に出力してください。
n
a_1 a_2 ... a_n
期待する出力
a_1 から a_n の整数を昇順に並び替えて、出力してください。
最後は改行し、余計な文字、空行を含んではいけません。
すべてのテストケースにおいて、以下の条件をみたします。
1 ≦ n ≦ 100
-3,000,000 ≦ a_i ≦ 3,000,000 (ただし、1 ≦ i ≦ n)
入力例
8
90 777 8888 121 333 4 29 2
出力例
2
4
29
90
121
333
777
8888
並び替えかぁ。VBA ではちょっと面倒なんだよな。やってみる。
Python
n = int(input())
li = [int(x) for x in input().split()]
for v in sorted(li):
print(v)
VBA
Sub sort_asc_2()
N = Cells(1, 1)
tmp = Split(Cells(2, 1), " ")
Dim a() As Variant
ReDim a(N - 1)
For i = 0 To N - 1
a(i) = Val(tmp(i))
Next
Call QuickSort(a, LBound(a), UBound(a))
For Each v In a
Debug.Print v
Next
End Sub
Private Sub QuickSort(ByRef argAry() As Variant, ByVal lngMin As Long, ByVal lngMax As Long)
Dim i As Long
Dim j As Long
Dim vBase As Variant
Dim vSwap As Variant
vBase = argAry(Int((lngMin + lngMax) / 2))
i = lngMin
j = lngMax
Do
Do While argAry(i) < vBase
i = i + 1
Loop
Do While argAry(j) > vBase
j = j - 1
Loop
If i >= j Then Exit Do
vSwap = argAry(i)
argAry(i) = argAry(j)
argAry(j) = vSwap
i = i + 1
j = j - 1
Loop
If (lngMin < i - 1) Then
Call QuickSort(argAry, lngMin, i - 1)
End If
If (lngMax > j + 1) Then
Call QuickSort(argAry, j + 1, lngMax)
End If
End Sub
文字と整数の組のソート (paizaランク C 相当)
1行目に行数を表す整数 n、続く n 行の各行で「文字」と「整数」の組が空白区切りで入力されます。
n 個の組を、「整数」の値で昇順に並べ変え、「文字」を出力してください。
n
S_1 D_1
S_2 D_2
...
S_i D_i
...
S_n D_n
S_i は「文字」で、D_i は「整数」です。
入力される文字 S_i は、同じ文字が複数入力されることはなく、整数 D_i も同様です。
期待する出力
n 個の組を、「整数」の値で昇順に並べ変え、「文字列」を1行ずつ出力してください。
すべてのテストケースにおいて、以下の条件をみたします。
・1 ≦ n ≦ 100
・-10,000 ≦ D_i ≦ 10,000
・S_iは半角英文字1文字
・iとjが異なるなら、D_iとD_jは異なる
・iとjが異なるなら、S_iとS_jは異なる
入力例
3
G 0
S 3
E -2
出力例
E
G
S
組み合わせでの並び替えかぁ。VBA ではかなり面倒なんだよな。やってみる。
Python
n = int(input())
li = [None] * n
for i in range(n):
s,d = input().split()
d = int(d)
li[i] = (d,s)
for d,s in sorted(li):
print(s)
VBA
Sub sort_asc_9()
N = Cells(1, 1)
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
For i = 1 To N
tmp = Split(Cells(i + 1, 1), " ")
dic.Add Val(tmp(1)), tmp(0)
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_dic(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
For Each v In dic
Debug.Print dic(v)
Next
End Sub
Private Sub QuickSort_dic(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 arrList(i, 0) < valMEDIAN
i = i + 1
Loop
'インデックスの大きい方から値を比較していく
Do While arrList(j, 0) > valMEDIAN
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_dic(arrList, minIDX, i - 1)
If (maxIDX > j + 1) Then Call QuickSort_dic(arrList, j + 1, maxIDX)
End Sub
最後に
Python では数行のコードが、VBA ではなかなかの力作に。VBA だけでなく、模範解答にある、C++ や PHP でも Python ほど簡潔には書けない。なんとも便利。
VBA のクイックソートは早いのだけれど、面倒だ。連想配列用に配列用、それぞれに文字で並べ替え用、数値で並べ替え用、さらに昇順用、降順用と、バリエーション豊富に用意しておかなければならない。
引き続き、よろしくお願いいたします!
ディスカッション
コメント一覧
まだ、コメントがありません