【プログラミング初心者】Swift練習問題~繰り返し1~ 回答例


以下で投稿した問題の回答例です。
https://qiita.com/euJcIKfcqwnzDui/items/f87eea73729284757711

練習問題

練習問題1

回答例

func printTexts(texts: [String]) {
    for text in texts {
        print(text)
    }
}

解説

引数として受け取ったtextsを1つずつ取り出し、取り出したtextprint()で出力しています。

練習問題2

回答例

func printTexts(texts: [String]) {
    var index = 0
    while index < texts.count {
        print(texts[index])
        index += 1
    }
}

解説

indexを配列番号として定義しています。
1ループごとにindex += 1し1ずつアクセスする配列番号を移動させていきます。
ループの継続条件はindex < texts.countとしています。
配列の要素数が3個の場合texts.count == 3です。
初回ループのときindex == 0なのでindex < texts.count、つまり「0 < 3」の結果はtrueとなり処理ブロックに入ります。
index += 1indexの値を更新します。
2回目のループは「1 < 3」、3回目ループは「2 < 3」となりtrue。
4回目ループでは「3 < 3」でfalseとなるためループ処理には入らず終了となります。

注意したいのはindex <= texts.countとしないことです。
「3 <= 3」はtrueなので4ループ目に入ります。
配列番号は0~[要素数 - 1]なのでtexts[3]は存在しません。
存在しない要素にアクセスするとクラッシュします。

練習問題3

回答例

func printCombine(texts: [String]) {
    var combinedText = ""
    for text in texts {
        combinedText = combinedText + text
    }
    print(combinedText)
}

解説

最終的に表示する内容としてcombinedTextを定義しています。
ループ処理の中でcombinedText = combinedText + textとしてcombinedTextの値を更新していきます。
text["Hello", "World", "!"]とすると
1ループ目でcombinedTextは「Hello」、2ループ目で「HelloWorld」...のように更新されています。

応用問題

応用問題1

回答例

func printLoop(text: String, loop: Int) {
    var index = 0
    while index < loop {
        print(text)
        index += 1
    }
}

または

別解
func printLoop(text: String, loop: Int) {
    for _ in 0..<loop {
        print(text)
    }
}

解説

応用と位置づけましたが【練習問題2】と内容は変わりません。

別解の方は0..<loopすることで[0, 1, 2, ..., (loop - 1)]の整数配列を作っています。
その配列数の個数分ループを回しています。
取りだした値自体は使用しないので_としています。
Swiftではこちらの書き方が一般的です。

応用問題2

回答例

func power(_ base: Double, exponent: Int) -> Double {
    var result = 1.0
    if exponent >= 0 {
        for _ in 0..<exponent {
            result = result * base
        }
    } else {
        let absoluteExponent = -exponent
        for _ in 0..<absoluteExponent {
            result = result / base
        }
    }

    return result
}

解説

べき乗の特性として指数の値が正、負、0によって計算の仕方がことなります。
そのためif文を使ってそれぞれ場合分けをしてあげます。

exponentが0の場合

exponentが0の場合、数値の0乗は1なのでresultの初期値として1を入れています。
exponent >= 0はtrueとなりifの処理ブロックに入りますが、0..<0の要素数は0なのでそのままforの処理ブロックには入らずreturn resultとなり1がそのまま返ります。
if exponent == 0 { return 1 }と明示的に処理を書いてあげてもOKです。

exponentが正の場合

exponentが正の場合、べき乗は指数の数だけ元の値を掛けていくという計算なのでexponentの回数掛け算を行ないます。

exponentが負の場合

exponentが負の場合、指数の絶対値の回数分元の値で割るという計算になります。
従ってresult = result / baseという処理になります。
let absoluteExponent = -exponentでは符号を反転させています。
符号を反転させず0..<absoluteExponentとするとSwiftはクラッシュします。
符号を反転させずexponent..<0としてあげても正解です。
この場合exponent..<0[exponent, exponent -1, ..., -1]という配列を返します。

最後に

別の問題は以下に掲載しています。
また本記事とは別でプログラミング未経験からiOSアプリ開発が行えるようになることを目的とした記事を連載しています。
連載も以下にまとめていますのでそちらも是非もご覧ください。
アジェンダ:https://qiita.com/euJcIKfcqwnzDui/items/0b480e96166e88945684