競技プログラミング用 知識集積所

if分岐

最終更新:

sport_programming

- view
管理者のみ編集可


雑な説明

変数の中身次第で特定のコードを実行したりしなかったりする。
あるいは、複数のコードのどれを実行するか選ぶ。

レベル

ABCのA問題以降。

基本的な記述

コードを実行したりしなかったりする

if (条件式) {
  その場合に実行したいコード
}
実行したいコードが1行しかない場合は
if (条件式) その場合に実行したいコード
でもよい。

2つのコードのどちらを実行するか選ぶ

if (条件式) {
  その場合に実行したいコード
} else {
  そうじゃない場合に実行したいコード
}
実行したいコードが1行しかない場合は
if (条件式) その場合に実行したいコード
else そうじゃない場合に実行したいコード
でもよい。

3つ以上のコードのどれを実行するか選ぶ

if (条件1) {
  条件1を満たす場合に実行したいコード
} else if (条件2) {
  条件1を満たさないが条件2を満たす場合に実行したいコード
} else {
  条件1も条件2も満たさない場合に実行したいコード
}
else if のところを増やしていけば、4択や5択、それ以上も可能。
実行したいコードが1行しかない場合については同様。

条件式に使える基本的な記述

等しい a==b

整数型の場合は、数値が等しければtrue。
double型の場合は、数値が等しければtrue……だが、あまり信用ならない(詳細はdouble型の注意点参照)
char型の場合は、同じ文字であればtrue。
string型の場合は、完全に同じ文字列であればtrue。
pair※tuple※vectorの場合は、個数と順番まで含め完全に同じ内容であればtrue。
set※の場合は、完全に同じ内容であればtrue。

等しくない a!=b

==がfalseになるならtrue。

より小さい a<b

整数型の場合は、数値がaの方が小さければtrue。
double型の場合は、数値がaの方が小さければtrue……だが、あまり信用ならない場合がある(詳細はdouble型の注意点参照)
char型の場合は、aの方がASCIIコードが小さければtrue。
string型の場合は、前から順に見て最初に異なる文字のところを探し、そこのASCIIコードがaの方が小さければ、またはaの方だけもう文字が尽きていればtrue。
pair※tuple※vectorの場合も前から順に見て最初に内容の異なるところを探し、そこがaの方が小さければ、またはaの方だけもう内容が尽きていればtrue。

以下 a<=b

a<bかa==bが成り立てばtrue。

より大きい a>b

b<aが成り立てばtrue。

以上 a>=b

a>bかa==bが成り立てばtrue。

発展的な記述

aとbの間の数という判定

真面目に書くと、
if ((a<x&&x<b)||(b<x&&x<a))
とすることになり、やや煩雑。

実はこれ、
if ((x-a)*(x-b)<0)
と書ける。
ただし桁あふれに注意。

あるいは、
if (min(a,b)<x&&x<max(a,b))
とも書ける。

そうじゃなければ、という条件(B問題レベル)

if (!条件) {
  そうじゃない場合に実行したいコード
}
と書くことで、条件が成り立たなければ実行、を書くことができる。
単純な条件なら逆の意味の記号があるので必要ないが、例えば「queue※が空じゃなかったら」という条件を
if (!q.empty())
と書くような場合に必要になる。

2つの条件をどちらもチェックしたい場合

2つの条件が両方成り立つなら実行、という場合は
if (条件1&&条件2)
2つの条件が片方だけでも成り立つなら実行、という場合は
if (条件1||条件2)
と書く。詳細はbool型参照。
3つや4つでも、個数が定まっているなら同様に書ける。

また、このとき、条件1の結果によっては、条件2がチェックされない。
つまり、
if (条件1&&条件2)
において条件1がfalseだった場合、条件2は確認せずに全体をfalseとして処理する。
これを利用すると、条件2での範囲外アクセスのエラーを防ぐことができる。

例えば、aというベクトルに対し、
if (a.size()>10&&a.at(10)>0)
と書くことで「10番目が正の数ならtrue、正の数でないかそもそも存在しなければfalse」と書ける。
(例えばaの長さが5であった場合、1つめの条件でfalseになるため2つめの判定が行われず、範囲外アクセスが発生しない)

同様に、
if (条件1||条件2)
において条件1がtrueだった場合、条件2は確認せずに全体をtrueとして処理する。
これもやはり条件2での範囲外アクセスのエラーを防ぐことができる。

多数(不定個)の条件を全てチェックしたい場合

bool型変数を用意して(または類する何らかの変数を用意して)forループで確認する。
詳細はbool型参照。

注意点

等しいと書くつもりで誤って=と書かないこと。

もし
if (x=0)
と書いた場合、意図と違う挙動をする。
これは、条件部分にbool型以外の値が入っていた場合でもそれぞれtrue扱いやfalse扱いにすると定めてあるため。
バグの発見が非常にしにくいので注意。
謎のWAが出た場合はとりあえずif文の中身を一通り確認してみる、くらいに警戒が必要。

類似アルゴリズム

whileループ

if分岐と似ているが、条件に合う限り何度でも繰り返して実行する。
ウィキ募集バナー