MySQLのこと。

MySQLのことについてまとめているブログ。他人に見せる用でもなく、自分の勉強備忘録。検索インデックスも外してるので、辿りついた方・・・ようこそ。そんな大した情報ないですよ?!たまにアルゴリズムの練習も

インデックスと仲良くなりたい。

range

for文やwhile文を使って、何らかの問題を解く際に、インデックスをうまく動かす必要がある。そうすることで配列の値をうまく動かせるので、インデックスとは仲良くないといけない。とりあえず簡単にrangeの使い方をまとめておく。以降、ここではlen_array5とする。

5回繰り返したいのであれば、range()に数値ないし数値が入っている変数を入れればよい。そうすれば0,1,2,3,4とインデックスが動き、5回の繰り返しが行われる。


len_array = 5

for i in range(len_array):
    print('i={}'.format(i), end=' ')

i=0 i=1 i=2 i=3 i=4 

このように指定しても、0,1,2,3,4とインデックスが動き、5回の繰り返しが行われる。インデックス0からインデックス4まで、1間隔で繰り返したいというような意味。


for i in range(0, 5, 1):
    print('i={}'.format(i), end=' ')

i=0 i=1 i=2 i=3 i=4 

この数字の渡し方を反対にして、間隔を-1にすると、4,3,2,1,0とインデックスを逆から動かせる。ijなんかのインデックスがあるループを考えた際に、これを使えばiは大きくなるけど、jは小さくなる、みたいなインデックスの動かし方ができる。


for i in range(4, -1, -1):
    print('i={}'.format(i), end=' ')

i=4 i=3 i=2 i=1 i=0 

while文

while文の基礎をまとめておく。while文は判定条件にあわせてループし続ける。1個目のものはi < len_arrayという条件なので、ilen_arrayよりも小さい間はループし続けるということになる。ループの度にインクリメントされるので、0,1,2,3,4で判定がFalseとなりループが終了する。


i = 0
while i < len_array:
    print('i={}'.format(i), end=' ')
    i += 1

i=0 i=1 i=2 i=3 i=4

while True:
    if i >= len_array:
        break
    print('i={}'.format(i), end=' ')
    i += 1
i=0 i=1 i=2 i=3 i=4

while文とfor文の使い分けはこんな感じなのだろうか。

  • ある入力が行われるまで繰り返す
  • ある値に達するまで繰り返す
  • 無限に繰り返す

breakとcontinue

こんなwhile文があったとして、途中でループを抜けたい、ループ途中で処理を飛ばしたい場合にbreakcontinueが役立つ。i >= len_arrayという条件が満たされるとループが終了するし、i == 3の場合、print()が実行されないので、0,1,2,4とインデックスが動く。


i = 0
while True:
    if i >= len_array:
        break
    if i == 3:
        i += 1
        continue
    print('i={}'.format(i), end=' ')
    i += 1

i=0 i=1 i=2 i=4 

while else

while elseは、while文が終了した際に実行される。この場合、インデックスが0,1,2,3,4とループが終了した後に、While Else Execというprint()が実行される。


i = 0
while i < len_array:
    print('i={}'.format(i), end=' ')
    i += 1
else:
    print('While Else Exec')

i=0 i=1 i=2 i=3 i=4 While Else Exec

breakが実行された場合、インデックスが0,1,2,3でループが終了する。


i = 0
while i < len_array:
    if i == 4:
        break
    print('i={}'.format(i), end=' ')
    i += 1
else:
    print('While Else Exec')

i=0 i=1 i=2 i=3 

インデックスと仲良くなる

基本的なおさらいが終わったので、ここからが本題。インデックスと仲良くなる。while文でfor文を表すことができるし、逆にfor文でwhile文を表すことができるので、2重のfor-forfor-whileで書き直し、色んなパターンでやっていく。いろんな書き方できると思うけど、あくまでも一例。

2重ループ

2重ループをfor文とwhile文でやっていく。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    for j in range(len_array):
        print('j={}'.format(j), end=' ')
    print()

i=0 j=0 j=1 j=2 j=3 j=4
i=1 j=0 j=1 j=2 j=3 j=4
i=2 j=0 j=1 j=2 j=3 j=4
i=3 j=0 j=1 j=2 j=3 j=4
i=4 j=0 j=1 j=2 j=3 j=4

j = 0を初期化する場所はiのループの中にする。


i = 0
while i < len_array:
    print('i={}'.format(i), end=' ')
    j = 0
    while j < len_array:
        print('j={}'.format(j), end=' ')
        j += 1
    i += 1
    print()

i=0 j=0 j=1 j=2 j=3 j=4
i=1 j=0 j=1 j=2 j=3 j=4
i=2 j=0 j=1 j=2 j=3 j=4
i=3 j=0 j=1 j=2 j=3 j=4
i=4 j=0 j=1 j=2 j=3 j=4

ド頭でiと一緒に初期化するとうまく行かない。jiの1回目のループで5までインクリメントされるので、iの2回目のループで、j < len_arrayFalseになってしまうので。


i = 0
j = 0
while i < len_array:
    print('i={}'.format(i), end=' ')
    while j < len_array:
        print('j={}'.format(j), end=' ')
        j += 1
    i += 1
    print()

i=0 j=0 j=1 j=2 j=3 j=4 
i=1 
i=2 
i=3 
i=4 

内側jのwhile文の回数を外側iのfor文の値で制御

内側のループの回数を外側のループの値で制御する。iのループの度に、jのループの回数を減らす。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    for j in range(len_array - i):
        print('j={}'.format(j), end=' ')
    print()

i=0 j=0 j=1 j=2 j=3 j=4 
i=1 j=0 j=1 j=2 j=3 
i=2 j=0 j=1 j=2 
i=3 j=0 j=1 
i=4 j=0 

while文の部分でlen_array - iとすると、iがインクリメントされる度に、jの終了条件が小さくなるので、このようなインデックスの動きになる。jのインデックスは大きくしていきたいので、j += 1でインクリメントする。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = 0
    while len_array - i > j:
        print('j={}'.format(j), end=' ')
        j += 1
    print()

i=0 j=0 j=1 j=2 j=3 j=4 
i=1 j=0 j=1 j=2 j=3 
i=2 j=0 j=1 j=2 
i=3 j=0 j=1 
i=4 j=0 

さきほどのjのインデックスが大きい方から始まる版。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    for j in range(len_array-i-1, -1, -1):
        print('j={}'.format(j), end=' ')
    print()

i=0 j=4 j=3 j=2 j=1 j=0 
i=1 j=3 j=2 j=1 j=0 
i=2 j=2 j=1 j=0 
i=3 j=1 j=0 
i=4 j=0 

ここではj = len_array-i-1として、iがインクリメントされる度に、jの条件を小さくする。jのインデックスは小さくしていきたいので、j -= 1でデクリメントする。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = len_array-i-1
    while j >= 0:
        print('j={}'.format(j), end=' ')
        j -= 1
    print()

i=0 j=4 j=3 j=2 j=1 j=0 
i=1 j=3 j=2 j=1 j=0 
i=2 j=2 j=1 j=0 
i=3 j=1 j=0 
i=4 j=0 

似たような感じなので説明はなし。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    for j in range(i + 1):
        print('j={}'.format(j), end=' ')
    print()

i=0 j=0 
i=1 j=0 j=1 
i=2 j=0 j=1 j=2 
i=3 j=0 j=1 j=2 j=3 
i=4 j=0 j=1 j=2 j=3 j=4 

for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = 0
    while j <= i:
        print('j={}'.format(j), end=' ')
        j += 1
    print()

i=0 j=0 
i=1 j=0 j=1 
i=2 j=0 j=1 j=2 
i=3 j=0 j=1 j=2 j=3 
i=4 j=0 j=1 j=2 j=3 j=4 

さきほどはjが0始まりだったけど、こっちはお尻のインデックス始まり。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    for j in range(i, -1, -1):
        print('j={}'.format(j), end=' ')
    print()

i=0 j=0 
i=1 j=1 j=0 
i=2 j=2 j=1 j=0 
i=3 j=3 j=2 j=1 j=0 
i=4 j=4 j=3 j=2 j=1 j=0 

for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = i
    while j >= 0:
        print('j={}'.format(j), end=' ')
        j -= 1
    print()

i=0 j=0 
i=1 j=1 j=0 
i=2 j=2 j=1 j=0 
i=3 j=3 j=2 j=1 j=0 
i=4 j=4 j=3 j=2 j=1 j=0 

剰余とかもつかってみる

割り算のあまりである剰余を使うと、特定の規則的を使いつつインデックスを操作できる。例えば、jのループはj % 2 == 0Trueのときだけ実行する。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = i
    while j >= 0 and j % 2 == 0:
        print('j={}'.format(j), end=' ')
        j -= 1
    print()

i=0 j=0 
i=1 
i=2 j=2 
i=3 
i=4 j=4 

他にも、while文のループはiつまりj % 2 == 0Trueのときだけ実行する。


for i in range(len_array):
    print('i={}'.format(i), end=' ')
    j = i
    if j % 2 == 0:
        while j >= 0:
            print('j={}'.format(j), end=' ')
            j -= 1
    print()

i=0 j=0 
i=1 
i=2 j=2 j=1 j=0 
i=3 
i=4 j=4 j=3 j=2 j=1 j=0 

for文とwhile文の使い分け

例えば複利の計算で下記のように計算するとプログラムが強調される部分が異なる。for文の場合は「10年後」という何年繰り返すという条件が強調されている。つまり、回数指定が行われている繰り返し。


amount = 10000
year = 10
for i in range(10):
    amount *= 1.05
print('10 years later it will be {} yen.'.format(int(amount)))

10 years later it will be 16288 yen.

一方で、while文の場合は「20000円を超えるまで」が強調されているのがわかるのと、20000円を超えるのに何年ループさせればよいのかがわからないので(私はパッとわからない…泣)、このような場合はwhile文のほうが適している。つまり、回数指定がない繰り返しの場合。


amount = 10000
year = 0
while amount <= 20000:
    year += 1
    amount *= 1.05
print('It will be over 20000 yen in {} years.'.format(year))

It will be over 20000 yen in 15 years.

f(x)=0になるようなxを求めるアルゴリズムであるニュートン法なんかのプログラムを見ると、近似解を求めるために、誤差が許容範囲内になるまで繰り返すように記述されていたりするので、どんだけ繰り返せばよいのかわからないので、for文ではなくwhile文が適している。