資格道場 › レッスン一覧 › アルゴリズムとプログラミング
アルゴリズムとプログラミング・2/13・18分

数値を扱うアルゴリズムと計算問題

ゴール

引き算・割り算・シフトで数を計算する流れ図を、表に書き出して1行ずつ追えるようになる。あわせて、最短経路の数と符号の平均ビット数を、公式に当てはめて素早く計算できるようになる。

科目Aの計算問題は「流れ図を1行ずつ追う(トレース)」か「決まった公式に当てはめる」かのどちらかです。とくにユークリッドの互除法は、公開過去問で本試験6回・免除19回と出題が多いテーマです。手順さえ覚えれば確実に得点できるので、ここで取りこぼさないようにします。

このレッスンで稽古する(用語チェック・過去問)

このレッスンの全体像:武器は「トレース表」と「2つの公式」

今回の7テーマは、次の2種類に分かれます。

種類 テーマ 解き方
流れ図を追う 引き算で割り算/ユークリッドの互除法/10進→2進/シフトで掛け算/反復の収束 変数を列にした表を作り、1回ずつ値を書く
公式に入れる 格子の最短経路/平均ビット数 組合せ C(n,r)/「長さ×確率」の合計

トレースとは、流れ図やプログラムを手で1ステップずつ実行し、変数の値の変化を追うことです。頭の中だけで追うと、分岐の向きや何回目かを取り違えます。必ず表に書くのが、いちばん確実な対策です。

引き算の繰返しで割り算をする(商と余り)

結論:y を引けた回数が商 q、引けなくなったときの残りが余り r です。

商は割り算の答えの整数部分、余りは割り切れずに残った数です。たとえば、17個のみかんを5個ずつ袋に詰めると、3袋できて2個残ります。袋の数が商、残ったみかんが余りです。

flowchart TD
  A["q ← 0, r ← x"] --> B{"r < y ?"}
  B -- "No" --> C["r ← r − y, q ← q + 1"]
  C --> B
  B -- "Yes" --> D["終了(q=商, r=余り)"]

x=17、y=5 でトレースすると次のとおりです。

回 r q r<y?
開始 17 0 No
1 12 1 No
2 7 2 No
3 2 3 Yes → 終了

結果は q=3(17÷5 の商)、r=2(余り)です。選択肢は「商と余りを入れ替えたもの」と「x と y を入れ替えたもの」でひっかけてきます。引かれているのは x、引いているのは y なので、x÷y になります。

x=17個から y=5個ずつ引く55521回目2回目3回目残り引けた回数 3 = 商 q=3引けずに残った 2 = 余り r=2
17個から5個ずつ3回引けたので商は3、引けずに残った2が余りになる様子。

ユークリッドの互除法(最頻出・厚めに)

結論:2つの数の「大きい方から小さい方を引く(または割った余りに置き換える)」操作を繰り返すと、最後に残る数が最大公約数です。

**最大公約数(GCD)**は、2つの数を両方とも割り切れる数のうち最大のものです。たとえば 12 と 18 なら 6 です。ユークリッドの互除法は、これを速く求める古典的な手順です。

試験には2つの書き方が出ます。見た目は違いますが、どちらも答えは最大公約数です。

版 流れ図・関数の形 終わる条件 答え
引き算版 大きい方 ← 大きい方 − 小さい方 2つの値が等しくなる その等しい値
mod版(再帰) f(x, y) = f(y, x mod y) y = 0 になる そのときの x

mod は割り算の余り(x mod y = x を y で割った余り)、div は商の整数部分です。mod版は引き算版の「同じ数を何回も引く」部分を、1回の割り算で済ませたものです。

よく出る問われ方は3つです。

  • 比較は何回か:引き算の回数に、最後の「等しい」と判定する1回を足します。これを数え忘れるのが典型的なミスです。
  • 答えの値:途中に出てくる余りや初期値を答えに選ばせる選択肢があります。
  • 指定した順に実行させる初期値の関係:数字を入れずに a、b のまま追い、最後の「m=n」を式にします(例題参照)。
12 と 18 の最大公約数(引き算版)1218比較1:違う18−12=6126比較2:違う12−6=666比較3:等しいGCD=6引き算2回+等しい判定1回=比較3回
12と18で引き算版の互除法を追うと、引き算2回のあと等しいと判定する1回が加わり、比較は3回・答えは6になる。

10進数を2進数に変える(2で割る方法)

結論:2で割った余り(0か1)を下の桁から順に並べたものが2進数です。 商は次の割り算に使います。

j=13 なら、13→余り1・商6、6→余り0・商3、3→余り1・商1、1→余り1・商0 です。下の桁から 1,0,1,1 と並ぶので、2進数では 1101 になります。

流れ図では、**先に余りを格納し(NISHIN(k) ← j mod 2)、あとで j を商に更新する(j ← j div 2)**という順番が大事です。順番を逆にすると、元の j の余りを取る前に j が変わってしまいます。選択肢は「div と mod の入れ替え」と「a と b の順番の入れ替え」でひっかけてきます。

j=13 を2で割り続ける余り1回目13 ÷ 2 → 商 612回目6 ÷ 2 → 商 303回目3 ÷ 2 → 商 114回目1 ÷ 2 → 商 01下から読む2進数11014回目3回目2回目1回目最初の余りがいちばん右(下の桁)
13を2で割り続けて出た余りを下から読むと、2進数の1101になる。

シフト演算と加算で掛け算をする

結論:小学校の筆算と同じです。乗数を1桁ずつ見て、その桁が1なら被乗数を足します。 1桁進むごとに、被乗数を左へ1つずらします。

シフトはビット列を左右にずらす操作です。論理シフトは、空いたところに0を入れるシフトです。

操作 値の変化 掛け算の中での役割
左シフト1ビット 2倍になる 被乗数 X を次の桁の重みに合わせる
右シフト1ビット 2で割る(端数は切り捨て) 乗数 Y の次の桁を第0ビットに持ってくる

第0ビットは最下位ビット(いちばん右の桁)です。毎回「Y の第0ビットを見る → 1なら Z に X を足す → X を左に、Y を右に1ビットずらす」を16回繰り返します。選択肢は「第15ビット(最上位)を見る」と「シフトの左右が逆」の組合せでひっかけてきます。Y を右にずらすなら、見るべきは毎回同じ第0ビットです。

反復の収束(不動点)

y ← f(x)、x ← y を繰り返して y が変わらなくなったら、次の f に入る x も y と同じ値です。つまり f(y) = y が成り立ちます。このような値を不動点と呼びます。f(a)=y は1回目だけの関係なので、ひっかけです。

格子の最短経路は「並べ方」の数

結論:右に m 回・上に n 回進む最短経路の数は C(m+n, n) です。

最短経路では、後戻りせずに右と上だけで進みます。そのため経路は、「右」と「上」の札を何通りに並べられるかと同じ数になります。組合せ C(n,r) は、n 個の中から r 個を選ぶ選び方の数で、C(5,2) = (5×4)÷(2×1) = 10 です。

条件 計算
寄り道なし C(右+上, 上)
途中の点 R を必ず通る (P→R の数) × (R→Q の数)(積の法則)

経由点がある問題では、つい足し算をしたり、R を無視して全体の数を数えたりしがちです。「〜を通って」と書かれていたら、2つの区間に分けて掛け算します。

最短経路=「右」「上」の札の並べ方PQ右 3回上 2回右右上右上5枚から「上」2枚の位置を選ぶC(5,2)=(5×4)÷(2×1)=10通り
右3回・上2回の最短経路は「右」「上」の札5枚の並べ方と同じで、太線はその10通りのうちの1つ。

符号の平均ビット数と一意に復号できる条件

結論:平均ビット数 = Σ(各文字のビット長 × 出現確率)です。 ビット長をただ平均するのではなく、よく出る文字ほど重く数えます。

一意に復号できるとは、つながったビット列を区切り方が1通りに決まる形で元に戻せることです。試験では、語頭条件(どの符号も、ほかの符号の先頭部分になっていない)を満たしていれば一意に復号できると判断して解けます。

符号の例 語頭条件 理由
a=0, c=00 ✕ 「00」が a,a か c か決まらない
a=0, b=01 ✕ 0 が 01 の先頭になっている
0 / 10 / 110 / 111 ○ どれもほかの符号の先頭になっていない

選び方は2段階です。まず語頭条件で候補を絞り、残った中で平均ビット数を比べます。いちばん短く見えても、復号できない符号は不正解です。

例題 1

互除法(引き算版):876 と 204 で比較は何回?

次の流れ図は,2 数 A, B の最大公約数を求めるユークリッドの互除法を,引き算の繰返しによって計算するものである。A が 876, B が 204 のとき,何回の比較で処理は終了するか。
流れ図: 開始 → [L←A; S←B] → 判断 L:S L:S の判断で,> のとき [L←(L−S)] を実行して判断 L:S に戻る。< のとき [S←(S−L)] を実行して判断 L:S に戻る。= のとき [A, B, L の出力] → 終了。

ア 4
イ 9
ウ 10
エ 11

出典:平成31年度 春期 基本情報技術者試験 午前 問7

解き方と答えを見る
  1. L=876、S=204 から始め、毎回の比較結果と更新後の値を表に書いていく
  2. 比較1:876>204 → L=876−204=672
  3. 比較2:672>204 → L=468
  4. 比較3:468>204 → L=264
  5. 比較4:264>204 → L=60
  6. 比較5:60<204 → S=204−60=144
  7. 比較6:60<144 → S=84
  8. 比較7:60<84 → S=24
  9. 比較8:60>24 → L=36
  10. 比較9:36>24 → L=12
  11. 比較10:12<24 → S=12
  12. 比較11:12=12 → 出力して終了(最大公約数は12)
  13. ここまでの引き算は10回。最後の「=」の判定を足して、比較は11回

答え:エ(11回)。引き算の回数10と取り違えない。

例題 2

指定した実行順になる初期値 a と b の関係

次の流れ図において,① → ② → ③ → ⑤ → ② → ③ → ④ → ② → ⑥ の順に実行させるために,①において m と n に与えるべき初期値 a と b の関係はどれか。ここで,a,b はともに正の整数とする。
流れ図: 開始 ① m ← a ; n ← b ② 判定 m : n (≠ のとき ③ へ、= のとき ⑥ へ) ③ 判定 m : n (< のとき ⑤ へ、> のとき ④ へ) ④ m ← (m - n) → ② に戻る ⑤ n ← (n - m) → ② に戻る ⑥ m の値を印字(平行四辺形) 終了

ア a = 2b
イ 2a = b
ウ 2a = 3b
エ 3a = 2b

出典:令和5年度 基本情報技術者試験 科目A 公開問題 問11

解き方と答えを見る
  1. m=a、n=b のまま、数字を入れずに追う
  2. ②→③→⑤:m≠n で、③では m<n(a<b)。⑤で n ← n−m なので、n = b−a
  3. ②→③→④:m≠n で、③では m>n。④で m ← m−n なので、m = a−(b−a) = 2a−b
  4. ②→⑥:ここで m=n になって終了するので、2a−b = b−a
  5. 整理すると 3a = 2b
  6. 確かめ:a=2、b=3 を入れると、n=3−2=1 → m=2−1=1 → m=n で、指定の順になる

答え:エ(3a = 2b)

例題 3

互除法(mod版):f(775, 527)

関数 f(x, y) が次のとおり定義されているとき,f(775, 527) の値は幾らか。ここで,x mod y は x を y で割った余りを返す。 f(x, y): if y = 0 then return x else return f(y, x mod y)

ア 0
イ 31
ウ 248
エ 527

出典:平成29年度 春期 基本情報技術者試験 午前 問6

解き方と答えを見る
  1. y≠0 なので f(527, 775 mod 527) を呼ぶ。775−527=248 なので f(527, 248)
  2. 527 mod 248:248×2=496、527−496=31 なので f(248, 31)
  3. 248 mod 31:31×8=248 で割り切れ、余り0 なので f(31, 0)
  4. y=0 なので x=31 を返す

答え:イ(31)。途中の 248 や初期値 527 はひっかけ。

例題 4

10進→2進の流れ図の a と b

次の流れ図は,10 進整数 j(0<j<100)を 8 桁の 2 進数に変換する処理を表している。2 進数は下位桁から順に,配列の要素 NISHIN(1) から NISHIN(8) に格納される。流れ図の a 及び b に入れる処理はどれか。ここで,j div 2 は j を 2 で割った商の整数部分を,j mod 2 は j を 2 で割った余りを表す。
流れ図: 開始 → j を入力 → ループ端「変換 k:1, 1, 8(注)」→ 処理 a → 処理 b → ループ端「変換」→ 終了。(注)ループ端の繰返し指定は,変数名:初期値,増分,終値 を示す。選択肢は a と b の組合せの表(ア: a=j ← j div 2, b=NISHIN(k) ← j mod 2 / イ: a=j ← j mod 2, b=NISHIN(k) ← j div 2 / ウ: a=NISHIN(k) ← j div 2, b=j ← j mod 2 / エ: a=NISHIN(k) ← j mod 2, b=j ← j div 2)

ア a: j ← j div 2 / b: NISHIN(k) ← j mod 2
イ a: j ← j mod 2 / b: NISHIN(k) ← j div 2
ウ a: NISHIN(k) ← j div 2 / b: j ← j mod 2
エ a: NISHIN(k) ← j mod 2 / b: j ← j div 2

出典:令和元年度 秋期 基本情報技術者試験 午前 問1

解き方と答えを見る
  1. j=13 で、ループ1回分の正しい順番を確かめる
  2. 先に余りを格納:NISHIN(1) ← 13 mod 2 = 1
  3. 次に商で更新:j ← 13 div 2 = 6
  4. 2回目:NISHIN(2) ← 0、j ← 3。3回目:NISHIN(3) ← 1、j ← 1。4回目:NISHIN(4) ← 1、j ← 0。5〜8回目はすべて0
  5. 下の桁から 1,0,1,1,0,0,0,0 → 2進数 00001101(=13)となり正しい
  6. したがって a = NISHIN(k) ← j mod 2、b = j ← j div 2

答え:エ

例題 5

シフトと加算による乗算(5×3 で確かめる)

次の流れ図は,シフト演算と加算の繰返しによって 2 進整数の乗算を行う手順を表したものである。この流れ図中の a,b の組合せとして,適切なものはどれか。ここで,乗数と被乗数は符号なしの 16 ビットで表される。X,Y,Z は 32 ビットのレジスタであり,桁送りには論理シフトを用いる。最下位ビットを第 0 ビットと記す。
流れ図: 開始 → [被乗数→X, 乗数→Y, 0→Z, 1→i] → ループ先頭の判定 [a : 1](= のとき (Z+X)→Z を実行、≠ のときはそれを飛ばす)→ [b] → [(i+1)→i] → 判定 [i : 16](> のとき「Z を出力する」→ 終了、≦ のときループ先頭の判定 a : 1 に戻る)。選択肢は a, b の組合せの表(列 a / 列 b)として提示。

ア a: Y の第 0 ビット,b: X を 1 ビット左シフト,Y を 1 ビット右シフト
イ a: Y の第 0 ビット,b: X を 1 ビット右シフト,Y を 1 ビット左シフト
ウ a: Y の第 15 ビット,b: X を 1 ビット左シフト,Y を 1 ビット右シフト
エ a: Y の第 15 ビット,b: X を 1 ビット右シフト,Y を 1 ビット左シフト

出典:平成29年度 春期 基本情報技術者試験 午前 問5

解き方と答えを見る
  1. 被乗数 X=101(5)、乗数 Y=011(3)、Z=0 とし、選択肢アの手順で追う
  2. i=1:Y の第0ビット=1 → Z=0+101=101。X を左シフトして 1010、Y を右シフトして 001
  3. i=2:Y の第0ビット=1 → Z=101+1010=1111(15)。X=10100、Y=000
  4. i=3〜16:Y の第0ビットはずっと0なので、Z は変わらない
  5. Z=15=5×3 となり正しい。第15ビットを見る方式や、シフトが逆の方式では成り立たない

答え:ア(a:Y の第0ビット、b:X を1ビット左シフト・Y を1ビット右シフト)

例題 6

R を通る格子の最短経路

図の線上を,点 P から点 R を通って,点 Q に至る最短経路は何通りあるか。
横5マス×縦4マスの格子。左下の格子点が P,右上の格子点が Q。R は左から 2 本目の縦線(左端を 0 として x=2)と下から 2 本目の横線(下端を 0 として y=2)の交点。

ア 16
イ 24
ウ 32
エ 60

出典:平成30年度 春期 基本情報技術者試験 午前 問2

解き方と答えを見る
  1. P を (0,0)、R を (2,2)、Q を (5,4) とする
  2. P→R:右2・上2 → C(4,2) = (4×3)÷(2×1) = 6 通り
  3. R→Q:右3・上2 → C(5,2) = (5×4)÷(2×1) = 10 通り
  4. R を通るので掛け算:6 × 10 = 60 通り
  5. (参考:R を無視すると C(9,4)=126 通り。足し算だと 16 になり、選択肢アのひっかけ)

答え:エ(60通り)

例題 7

1文字当たりの平均ビット数

表は,文字 A~E を符号化したときのビット表記と,それぞれの文字の出現確率を表したものである。1 文字当たりの平均ビット数は幾らになるか。
文字ビット表記出現確率(%)
A050
B1030
C11010
D11105
E11115

ア 1.6
イ 1.8
ウ 2.5
エ 2.8

出典:平成23年度 特別試験 基本情報技術者試験 午前 問3

解き方と答えを見る
  1. 各文字の「ビット長 × 確率」を計算する
  2. A:1 × 0.5 = 0.5
  3. B:2 × 0.3 = 0.6
  4. C:3 × 0.1 = 0.3
  5. D:4 × 0.05 = 0.2
  6. E:4 × 0.05 = 0.2
  7. 合計:0.5+0.6+0.3+0.2+0.2 = 1.8
  8. (ビット長をただ平均すると (1+2+3+4+4)÷5 = 2.8 で、選択肢エのひっかけ)

答え:イ(1.8)

例題 8

一意に復号できて最も短い符号

a,b,c,d の 4 文字から成るメッセージを符号化してビット列にする方法として表のア~エの 4 通りを考えた。この表は a,b,c,d の各 1 文字を符号化するときのビット列を表している。メッセージ中での a,b,c,d の出現頻度は,それぞれ 50%,30%,10%,10%であることが分かっている。符号化されたビット列から元のメッセージが一意に復号可能であって,ビット列の長さが最も短くなるものはどれか。
abcd
ア010011
イ0011011
ウ010110111
エ00011011

ア a:0,b:1,c:00,d:11
イ a:0,b:01,c:10,d:11
ウ a:0,b:10,c:110,d:111
エ a:00,b:01,c:10,d:11

出典:基本情報技術者試験 科目A免除 修了試験 20211212 実施分 問6

解き方と答えを見る
  1. 語頭条件を確かめる。ア:a=0 が c=00 の先頭にあり ✕
  2. イ:a=0 が b=01 の先頭にあり ✕
  3. ウ:0 / 10 / 110 / 111 はどれもほかの符号の先頭になっていない ○
  4. エ:全部2ビットで長さが同じなので ○
  5. ウの平均:1×0.5 + 2×0.3 + 3×0.1 + 3×0.1 = 0.5+0.6+0.3+0.3 = 1.7
  6. エの平均:2×1.0 = 2.0
  7. 1.7 < 2.0 なのでウ

答え:ウ

要点(試験直前に読む)

  • 互除法は、引き算版なら「等しくなったら終了」、mod版なら「y=0 で x を返す」。答えは最大公約数で、比較回数は引き算の回数+1。
  • 初期値の関係を問う問題は、a・b を文字のまま追い、最後の m=n を式にする。
  • 10進→2進は、余りを先に格納してから商で更新する。余りは下の桁から並ぶ。
  • シフトで掛け算をするときは、Y の第0ビットを見て、1なら Z+X。X は左、Y は右に1ビットずつずらす。
  • 最短経路の数は C(右+上, 上)。経由点があるときは区間ごとに求めて掛け算する。
  • 平均ビット数は Σ(長さ×確率)。比べる前に、語頭条件で復号できない符号を外す。

ひっかけ

  • 互除法の比較回数:引き算の回数(例:10)を選ばせてくる。最後の「=」の判定1回を足す。
  • 商と余り、x÷y と y÷x を入れ替えた選択肢:引かれる側(x)が割られる数、引いた回数が商。
  • シフト乗算:第15ビットを見る方式や、左右逆のシフトが混ざる。5×3 など小さな数で1回試せば見破れる。
  • 経由点のある最短経路:足し算(6+10=16)や、R を無視した全体の数は誤り。「通って」は掛け算。
  • 符号問題:平均が短くても、a=0 と c=00 のように先頭がかぶる符号は復号できないので不正解。

用語(16)

商 しょう
割り算の答えの整数部分。
⚠ 余りと入れ替えた選択肢が出る。「何回引けたか」が商、「最後に残った数」が余り。
余り あまり
割り切れずに残った、割る数より小さい数。
⚠ 商と取り違えやすい。余りは必ず割る数より小さい。
mod modulo(モジュロ)
x mod y は、x を y で割った余りを返す演算。
⚠ div は商を返す。mod は余り、div は商。
div division(ディビジョン)
x div y は、x を y で割った商の整数部分を返す演算。
⚠ mod(余り)と入れ替えた選択肢が出る。
最大公約数 さいだいこうやくすう(GCD:Greatest Common Divisor)
2つの数をどちらも割り切れる数のうち、最大のもの。
⚠ 最小公倍数(両方の倍数のうち最小のもの)とは別物。
ユークリッドの互除法 ゆーくりっどのごじょほう
大きい方を「差」または「割った余り」に置き換える操作を繰り返して、最大公約数を求める手順。
⚠ 引き算版は2つの値が等しくなったら終わり、mod版は y=0 になったら終わり。比較回数は、引き算の回数+最後の1回。
トレース trace
流れ図やプログラムを手で1ステップずつ実行して、変数の値の変化を追うこと。
再帰 さいき
関数が自分自身を呼び出して処理を進める書き方。
⚠ ループと同じことを、関数の呼び出しで書いたもの。終了条件(例:y=0)を必ず探す。
2進数 にしんすう
0と1だけで表し、桁が1つ上がるごとに重みが2倍になる数の表し方。
⚠ 10進→2進の変換では、余りは下の桁から順に並ぶ(上の桁からではない)。
論理シフト ろんりしふと
ビット列を左右にずらし、空いた桁に0を入れる操作。
⚠ 算術シフトは符号ビットを保つ。左シフトは2倍、右シフトは2で割る。
最下位ビット さいかいびっと(LSB:Least Significant Bit)
ビット列のいちばん右の桁で、この問題では第0ビットと呼ぶ。
⚠ 最上位ビット(MSB・16ビットなら第15ビット)。乗算の流れ図で見るのは第0ビット。
不動点 ふどうてん
関数に入れても値が変わらない点で、f(y)=y を満たす y のこと。
⚠ f(a)=y は1回目の結果にすぎず、収束の条件ではない。
組合せ くみあわせ(C(n,r))
n 個から順番を考えずに r 個を選ぶ選び方の数で、C(n,r)=n!÷(r!(n−r)!)。
⚠ 順列 P(n,r) は並ぶ順番も区別する。最短経路の数は C を使う。
積の法則 せきのほうそく
「Aをしてから続けてBをする」場合の数は、Aの数×Bの数になるという考え方。
⚠ 和の法則(AまたはB)は足し算。「〜を通って」なら掛け算。
平均符号長 へいきんふごうちょう
各文字のビット長に出現確率を掛けて足し合わせた、1文字当たりのビット数の期待値。
⚠ ビット長をただ平均したもの(確率を無視)と取り違えやすい。
語頭条件 ごとうじょうけん(接頭語条件・prefix condition)
どの符号も、ほかの符号の先頭部分になっていないという条件。
⚠ 満たしていれば一意に復号できる。短さだけで選ぶと、この条件を見落とす。

このレッスンの過去問

このレッスンで稽古する