第129回【Python】指定要素の検索、指定要素の検索 (query)
現在取り組んでいるのは、paiza ラーニング問題集「クエリメニュー」になります。
はじめに
猫とキャンプと野球観戦と AWS が大好きな旦那、LeoSaki です。モフモフしたい。
Python をゼロから勉強してみよう、のコーナー 129 回目です。
キャンプ場の夜の過ごし方は Amazon Prime で適当な番組を見て過ごす、です。重宝しているのは、ダイソーの Bluetooth スピーカー(レトロタイプ)。以前はタブ PC からの音量の調整に苦労していました。今は手元で自分たちだけに聞こえるよう音量調節できるので楽ちんです。
それでは、今日も頑張ってみようと思います。
指定要素の検索
長さ N の重複した要素の無い数列 A と整数 K が与えられるので、
A に K が含まれていれば “YES" を、そうでなければ “NO" を出力してください。
N K
A_1
...
A_N
・1 行目では、配列 A の要素数 N と検索する値 K が半角スペース区切りで与えられます。
・続く N 行では、配列 A の要素が先頭から順に与えられます。
すべてのテストケースにおいて、以下の条件をみたします。
・1 ≦ N ≦ 100,000
・0 ≦ A_i , K ≦ 1,000,000 (1 ≦ i ≦ N)
入力例
3 5
1
3
5
出力例
YES
最大値が 100,000 となっている。境界値のテストケースで一つずつ検索をかけるとちょっと時間がかかりそう。
Python
N,K = map(int,input().split())
A = [int(input()) for _ in range(N)]
print("YES" if K in A else "NO")
in 演算子の計算量は O(N) で、効率的というわけではない。
VBA
Sub query_primer__single_search()
s = Split(Cells(1, 1), " ")
N = Val(s(0))
K = Val(s(1))
Dim A() As Long
ReDim A(N - 1)
For i = 0 To N - 1
A(i) = Cells(i + 2, 1)
Next
Do
For i = LBound(A) To UBound(A)
If A(i) = K Then
Debug.Print "YES"
Exit Do
End If
Next
Debug.Print "NO"
Loop While False
End Sub
最近お気に入りの Do Loop 1 回抜け。Python の For else 文の真似事のつもりです。フラグ管理とかより、わかりやすい気がしています。
指定要素の検索 (query)
長さ N の重複した要素の無い数列 A と Q 個の整数 K_1 … K_Q が与えられるので、
各 K_i について、 A に K_i が含まれていれば “YES" を、そうでなければ “NO" を出力してください。
N Q
A_1
...
A_N
K_1
...
K_Q
・1 行目では、配列 A の要素数 N と検索する値の個数 Q が半角スペース区切りで与えられます。
・続く N 行では、配列 A の要素が先頭から順に与えられます。
・続く Q 行では、検索する値 K_1 .. K_Q が順に与えられます
すべてのテストケースにおいて、以下の条件をみたします。
・1 ≦ N , Q ≦ 100,000
・0 ≦ A_i ≦ 1,000,000 (1 ≦ i ≦ N)
・0 ≦ K_i ≦ 1,000,000 (1 ≦ i ≦ Q)
入力例
5 5
1
2
3
4
5
1
3
5
7
9
出力例
YES
YES
YES
NO
NO
10 万件と 10 万件の検索だと、最大で 100 億回の検索が必要。それはさすがに時間がかかりすぎる。
Python
N,Q = map(int,input().split())
A = { int(input()) for _ in range(N) }
for _ in range(Q):
K = int(input())
if K in A:
print('YES')
else:
print('NO')
set を利用する。set はハッシュ法を利用しているため、in 演算子の計算量が平均で O(1) で実行できる。
VBA
Sub query_primer__multi_search()
NQ = Split(Cells(1, 1), " ")
N = Val(NQ(0))
Q = Val(NQ(1))
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary")
For i = 1 To N
A = Cells(i + 1, 1)
If Not dic.exists(A) Then
dic.Add A, A
End If
Next
For i = 1 To Q
K = Cells(N + i + 1, 1)
If dic.exists(K) Then
Debug.Print "YES"
Else
Debug.Print "NO"
End If
Next
End Sub
VBA のハッシュは連想配列らしい。
最後に
Python は、ほとんど一瞬で動きます。さて、VBA の方は・・・。paiza が用意してくれている境界値データを用いた場合で 1 分ちょっとくらいかかりました。早いっちゃ早い?
他の方法もいろいろと調べてみたのですが、VBA のハッシュは連想配列くらいしか見当たらなかったので、もっと早くできる方法があれば教えてください。ちなみに、100 で割った余りを key としてデータを分割、親連想配列とし、その中に子連想配列を入れ子にしてみたのですが、ちょっとかかる時間が大きくなりました。
引き続き、よろしくお願いいたします!
ディスカッション
コメント一覧
まだ、コメントがありません