2.3 反復処理:for, while

アルゴリズムの実装では,ほとんど同じ様な処理を何回も実行する必要がある場合がある. その様な場合,プログラムでも同じ処理をその文書くのではなく,forwhile文という構文を利用することで,繰り返し同じ処理を行うことができる.

また,同じ処理のなかで変更したい部分を変数化しておいて,処理すべきパターンをベクトルとして指定したりすることで,繰り返し処理の中でも指定した部分を変化させながら全て実行することができる.

2.3.1 for

for文は次のように記述する.

for (i in ベクトル) {
    処理
}

構文自体はとても簡単だが,非常に強力である. 例えば,tech-ml-studymeetingという文字列を一文字ずつ表示する処理である.

s <- "tech-ml-studymeeting"
n <- nchar(s) # 文字列の長さを取得
for (i in 1:n) {
    print(str_sub(s, i, i)) # i番目の文字列を表示
}
## [1] "t"
## [1] "e"
## [1] "c"
## [1] "h"
## [1] "-"
## [1] "m"
## [1] "l"
## [1] "-"
## [1] "s"
## [1] "t"
## [1] "u"
## [1] "d"
## [1] "y"
## [1] "m"
## [1] "e"
## [1] "e"
## [1] "t"
## [1] "i"
## [1] "n"
## [1] "g"

1:nというのは,既に紹介した通り,1からnまでの整数を順番に要素に持つベクトルである.

Exercise 2.3 (反復処理1)

  1. 1 ~ 100までの整数の合計を計算する処理を,for文を用いて実装せよ.
  2. tech-ml-studymeetingという文字列について,各文字を小文字ローマ字の順番で一つずらした文字を一つずつ表示させる処理を実装せよ.

小文字ローマ字のベクトルはlettersという変数が用意されているので,これを利用すると良い.

print(letters)
##  [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q"
## [18] "r" "s" "t" "u" "v" "w" "x" "y" "z"

また,特定の文字が何番目の要素であるかは以下のように調べることができる.

which(letters == "m") # m という文字がlettersの何番目の要素かを調べる処理
## [1] 13

2.3.2 while

while文はforと同じく反復処理を記述する構文である.forは指定されたベクトルの要素を順番にとりながら処理が繰り返されるのに対して,whileは条件式がTRUEである限り繰り返し処理が継続されるというものである.

ここで注意したいのは,与えられる条件式がFALSEになることがない場合,while文は終了することがない,つまり無限ループに陥るということである. そのためwhile文を実行する際には少し注意を払う必要がある.

while文は次のように書くことができる.

while (条件式) {
    処理
}

例えば,変数xに1000を代入して,x <- x/2xを2で割った数をxに代入しなおす)操作を繰り返しx0.0001よりも小さくなるまで繰り返す,という処理を実装してみよう.

注意として,条件式は結果がTRUEである限り繰り返す,ので,x0.0001よりも小さくなるまでという条件は,x0.0001以上である限り,と読み替えが必要である.

x <- 1000
i <- 0 # 繰り返し数をカウント
while(x > 0.0001) {
    i <- i + 1 # iに1を足す
    x <- x/2
}
print(i)
## [1] 24
print(x)
## [1] 5.960464e-05

結果として24回でx0.001よりも小さくなり処理を抜け出していることがわかる.