ショートコーディング goto文とループ

AIZU ONLINE JUDGEにあった問題を解いてみました。

void call(int n){
    int i = 1;
    CHECK_NUM:
    int x = i;
    if ( x % 3 == 0 ) {
        cout << " " << i;
        goto END_CHECK_NUM;
    }
    INCLUDE3:

    if ( x % 10 == 3 ) { 

        cout << " " << i; goto END_CHECK_NUM;
    }
    x /= 10;
    if ( x ) goto INCLUDE3;
    END_CHECK_NUM:
    if ( ++i <= n ) goto CHECK_NUM;
    cout << endl;
}

 

C++で書かれた上のコードをgoto文を使わずに書き直すという問題です。

 

構造化プログラミング | プログラミング入門 | Aizu Online Judge

プログラムを見ると、if文が四つありますよね。一つ目はxが3で割り切れた場合、i(xと同じ値です。)の値を表示してEND_CHECK_NUMに移動します。二つ目はxを10で割った余りが3である場合、iの値を表示し、END_CHECK_NUMに移動します。三つ目はxを10で割りその商をxに代入し、xが0でなければ、二つ目のif文の直前のINCLUDE3に移動します。ここはループになっていますね。ループから抜ける条件はxが0であるということ。四つ目はiをインクリメントしてn以下なら一番上にあるCHECK_NUMに移動します。ここもループになっています。ループから抜ける条件はiがnより大きいということ。ということで、goto文を使わずにループを使って書き換えてみます。

書き直されたコードはRubyで書かれているのですが、上の行に戻る処理はwhileループで、下の行に移動する処理はif文にスキップするかどうかのブール値をもたせた変数を追加して表現しています。