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

配列の添字操作と表計算の参照

ゴール

流れ図の「添字(何番目か)」を自分で追い、配列のずらし・連結・2次元配列の回転の空欄に入る式を選べるようになる。表計算で、式を複写しても正しいセルを参照する「$」の付け方も選べるようになる。

添字の取り違えは、プログラムの不具合で最も多い原因の一つです。そのため試験では「どの番号からどの番号へ移すか」を何度も問われます。現行の科目Bは擬似言語が中心で、科目Aでもアルゴリズムの読解が出ます。どちらも同じ添字の読み方を使います。

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

まず結論:添字問題は「小さい例で実際に動かす」と必ず解ける

配列の空欄問題は、頭の中で一般式を考えるより、要素3〜4個の具体例を作って選択肢に数字を入れる方が速く確実です。正解以外の選択肢は、具体例を1つ当てはめるだけで矛盾が出るように作られています。

  • 配列:同じ種類のデータを番号付きで並べた入れ物。マンションの部屋番号のように、番号で中身を取り出す
  • 添字(要素番号):配列の何番目かを表す番号。この試験では0から始まる場合と1から始まる場合があり、問題文で必ず確認する
  • ループ端の指定「i:初期値, 増分, 終値」:iをいくつから始め、いくつずつ変え、いくつで終えるか。「n−1, −1, 0」なら n−1 から 1 ずつ減らして 0 まで

流れ図の矢印「→」は「左を右へ入れる」

古い形式の流れ図では、「A → B」は「Aの値をBに入れる(代入する)」という意味です。擬似言語では向きが逆で「B ← A」と書きます。どちらも矢印の先が入れられる側です。

書き方 使われる場所 意味
TANGO[i] → TANGO[i+1] 流れ図(古い過去問) TANGO[i] の値を TANGO[i+1] に入れる
TANGO[i+1] ← TANGO[i] 擬似言語(科目B・新しい問題) 同じ意味

矢印の先が書き換わる側と覚えれば、表記が変わっても迷いません。

配列のずらし(シフト):後ろから動かすのが鉄則

要素を1つずつ後ろにずらすときは、大きい添字から順に処理します。前から動かすと、まだ移していない値を上書きして消してしまうからです。

たとえるなら、映画館の1列で全員が1席ずつ右へ詰めるとき、右端の人から先に動くのと同じです。左端の人から動くと、隣の席はまだ埋まっています。

過去問の形はこうです。

  1. 最後の要素 TANGO[n] を空いている TANGO[0] に退避(一時的に避難させること)する
  2. i を n−1 から 0 まで1ずつ減らしながら、TANGO[i] → TANGO[i+1]
  3. 最後の i=0 のとき TANGO[0](退避した値)が TANGO[1] に入り、先頭への移動が完成する
動かす方向 処理する順 理由
後ろへずらす(i → i+1) 大きい添字から(降順) 前から動かすと次に動かす値が消える
前へ詰める(i+1 → i) 小さい添字から(昇順) 後ろから動かすと次に動かす値が消える
T=TANGO[0][1][2][3]はじめ-ABC①退避 T[3]→T[0]CABCi=2 T[2]→T[3]CABBi=1 T[1]→T[2]CAABi=0 T[0]→T[1]CCABT[1]〜T[3] = C, A, B(Cが先頭へ)大きい添字から動かすので値が消えない
n=3 のとき、TANGO[3] を TANGO[0] に退避してから i=2,1,0 の順に後ろへずらすと、値が消えずに C が先頭へ回る(色付きの箱がその手順で書き換わる所)。

配列の連結:後半の書き込み位置は「前半の長さ+k」

連結とは、2つの並びをつないで1つにすることです。長さmのXの後ろに長さnのYをつなぐと、Zの1〜m番目にX、m+1〜m+n番目にYが入ります。

Yの1文字目はZのm+1番目に入るので、書き込み位置は Z(m+k) です。このように「先頭からいくつずらすか」を表す数をオフセットと呼びます。オフセットは前に置いたものの長さ(ここではm)であり、後ろの長さnではありません。

X(長さ m=3)Y(長さ n=2)X1X2X3Y1Y2ZX1X2X3Y1Y212345前半の長さ m=3 = オフセットY1 → Z(m+1) = Z(3+1) = Z4
長さ m=3 の X の後ろに長さ n=2 の Y をつなぐと、Y の k 文字目は Z(m+k) に入る(オフセットは前半の長さ m)。

2次元配列の回転・転置:1点ずつ「どこへ行ったか」を確かめる

2次元配列は、行と列の番号2つで場所を指す表です。A(i, j) は i行目・j列目を表します。回転や裏返しの問題は、図の中で**目立つ1点(端や角)**を選んで行き先を調べ、選択肢の式に当てはめて絞り込みます。

8×8(添字0〜7)の場合、よく出る変換は次のとおりです。

操作 式(B ← A(i, j)) イメージ
転置 B(j, i) 左上→右下の対角線で折り返す(行と列が入れ替わる)
左右反転 B(i, 7−j) 鏡に映す
上下反転 B(7−i, j) 上下逆さま
180度回転 B(7−i, 7−j) 上下と左右の両方を反転
時計回り90度 B(j, 7−i) Aの一番上の行がBの一番右の列になる
反時計回り90度 B(7−j, i) Aの一番上の行がBの一番左の列になる

式を暗記しなくても、1〜2点を当てはめれば解けます。

A時計回り90度B0707★●0707★●★ A(0, 0) → B(0, 7)● A(0, 7) → B(7, 7)どちらも式 B(j, 7−i) と一致Aの一番上の行がBの一番右の列になる
8×8 の A を時計回りに90度回すと、Aの一番上の行がBの一番右の列になる。★と●の2点を式 B(j, 7−i) に当てはめると行き先が一致する。

2次元配列の要素参照の計算

「a(i, j) の値は 2i+j」のように値が式で決まる問題は、内側のカッコから順に数値に置き換えます。添字そのものが計算結果になる二重構造なので、iとjを入れ替えないことだけに注意します。

表計算の絶対参照・相対参照

表計算ソフトでは、式を別のセルへ複写(コピー)すると、参照先も同じ方向へ自動でずれます。「$」を付けた部分だけはずれずに固定されます。

書き方 名前 複写したときの動き
B2 相対参照 行も列もずれる
$B$2 絶対参照 行も列も固定
$B2 複合参照(列固定) 列Bは固定・行はずれる
B$2 複合参照(行固定) 行2は固定・列はずれる

$は直後の記号を固定すると覚えます($Bなら列B、$2なら行2)。

C2の式を D3(1行下・1列右)へ複写BCD23=$B2=$B3列B固定行 2→3BCD23=B$2=C$2行2固定列 B→C
C2 の式を1行下・1列右の D3 へ複写すると、$ が付いた側だけ固定され、付いていない側は複写した方向へずれる。
例題 1

単語を1つずつ後ろにずらす流れ図の空欄

要素番号が 0 から始まる配列 TANGO がある。n 個の単語が TANGO[1] から TANGO[n] に入っている。図は,n 番目の単語を TANGO[1] に移動するために,TANGO[1] から TANGO[n−1] の単語を順に一つずつ後ろにずらして単語表を再構成する流れ図である。a に入れる処理として,適切なものはどれか。
流れ図(上から順に): 開始 → TANGO[n] → TANGO[0] → ループ(i : n−1, −1, 0) → [a] → ループ(端) → 終了 (注)ループにおける条件は,変数名:初期値,増分,終値 を示す。

ア TANGO[i] → TANGO[i+1]
イ TANGO[i] → TANGO[n−i]
ウ TANGO[i+1] → TANGO[n−i]
エ TANGO[n−i] → TANGO[i]

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

解き方と答えを見る
  1. 具体例を作る:n=4、TANGO[1]〜[4] = 「A, B, C, D」。目標は TANGO[1]〜[4] = 「D, A, B, C」。
  2. 最初の処理 TANGO[n] → TANGO[0] で TANGO[0]=D。配列(添字0〜4)は [D, A, B, C, D]。
  3. ループは i を n−1=3 から 0 まで1ずつ減らす。アの TANGO[i] → TANGO[i+1] を当てはめる。
  4. i=3:TANGO[3]=C を TANGO[4] へ → [D, A, B, C, C]
  5. i=2:TANGO[2]=B を TANGO[3] へ → [D, A, B, B, C]
  6. i=1:TANGO[1]=A を TANGO[2] へ → [D, A, A, B, C]
  7. i=0:TANGO[0]=D を TANGO[1] へ → [D, D, A, B, C]。TANGO[1]〜[4] = D, A, B, C で目標どおり。
  8. 確認:イの TANGO[i] → TANGO[n−i] では、i=3 のとき TANGO[3]=C が TANGO[1] へ入り、Aが消える。エは代入の向きが逆で、TANGO[n−i] から TANGO[i] へ入れてしまう。

答え:ア(TANGO[i] → TANGO[i+1])。後ろへずらすので、大きい添字から順に1つ後ろへ移す。

例題 2

XとYを連結してZに入れる流れ図の空欄

長さ m,n の文字列をそれぞれ格納した配列 X,Y がある。図は,配列 X に格納した文字列の後ろに,配列 Y に格納した文字列を連結したものを,配列 Z に格納するアルゴリズムを表す流れ図である。図中の a,b に入れる処理として,適切なものはどれか。ここで,1 文字が一つの配列要素に格納されるものとする。
流れ図(上から下): 開始 → ループ1[k:1, 1, m]→ 処理 a → ループ1 端 → ループ2[k:1, 1, n]→ 処理 b → ループ2 端 → 終了 (注)ループ端の繰返し指定は,変数名:初期値,増分,終値 を示す。 選択肢表:
ab
アX(k) → Z(k)Y(k) → Z(m + k)
イX(k) → Z(k)Y(k) → Z(n + k)
ウY(k) → Z(k)X(k) → Z(m + k)
エY(k) → Z(k)X(k) → Z(n + k)

ア a: X(k) → Z(k),b: Y(k) → Z(m + k)
イ a: X(k) → Z(k),b: Y(k) → Z(n + k)
ウ a: Y(k) → Z(k),b: X(k) → Z(m + k)
エ a: Y(k) → Z(k),b: X(k) → Z(n + k)

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

解き方と答えを見る
  1. 具体例を作る:m=3、X = 「A, B, C」。n=2、Y = 「D, E」。目標は Z(1)〜Z(5) = A, B, C, D, E。
  2. ループ1(k=1〜3)の a:X(k) → Z(k) で Z(1)=A、Z(2)=B、Z(3)=C。Xを先に入れるので、Yを使うウ・エは消える。
  3. ループ2(k=1〜2)の b をアの Y(k) → Z(m+k) で試す:k=1 で Z(3+1)=Z(4)=D、k=2 で Z(3+2)=Z(5)=E。目標どおり。
  4. イの Y(k) → Z(n+k) で試す:k=1 で Z(2+1)=Z(3)=D となり、CがDで上書きされる。k=2 で Z(4)=E となり、Z(5) は空のまま。

答え:ア(a:X(k) → Z(k)、b:Y(k) → Z(m+k))。後半の書き込み位置は「前半の長さm+k」。

例題 3

配列Aを回転させて配列Bにする操作

配列 A が図 2 の状態のとき,図 1 の流れ図を実行すると,配列 B が図 3 の状態になった。図 1 の a に入れる操作はどれか。ここで,配列 A,B の要素をそれぞれ A(i, j),B(i, j) とする。
図1 流れ図: 開始 → ループ1(i:0, 1, 7(注))→ ループ2(j:0, 1, 7(注))→ 処理 a → ループ2 終端 → ループ1 終端 → 終了。(注)ループ端の繰返し指定は,変数名:初期値,増分,終値 を示す。 図2 配列 A の状態(行 i=0..7 ↓,列 j=0..7 →,* の位置): i=0: j=1,2,3,4,5,6 i=1: j=1 i=2: j=1 i=3: j=1,2,3,4 i=4: j=1 i=5: j=1 i=6: j=1 i=7: j=1 図3 実行後の配列 B の状態(* の位置): i=0: なし i=1: j=0,1,2,3,4,5,6,7 i=2: j=4,7 i=3: j=4,7 i=4: j=4,7 i=5: j=7 i=6: j=7 i=7: なし

ア B(7-i, 7-j) ← A(i, j)
イ B(7-j, i) ← A(i, j)
ウ B(i, 7-j) ← A(i, j)
エ B(j, 7-i) ← A(i, j)

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

解き方と答えを見る
  1. 図2で目立つ点として、一番上の行の右端 A(0, 6) を選ぶ(i=0, j=6)。各選択肢でこの点の行き先を計算する。ア B(7−0, 7−6)=B(7, 1)。イ B(7−6, 0)=B(1, 0)。ウ B(0, 7−6)=B(0, 1)。エ B(6, 7−0)=B(6, 7)。
  2. 図3と照らす。0行目と7行目には*が無いので、アとウは消える。B(1, 0) は1行目にあり*がある。B(6, 7) も6行目の列7にあり*がある。イとエが残る。
  3. 2点目として、3行目の右端 A(3, 4) を選ぶ(i=3, j=4)。イ B(7−4, 3)=B(3, 3)。エ B(4, 7−3)=B(4, 4)。
  4. 図3の3行目は列4と列7だけなので、B(3, 3) には*が無くイは消える。4行目には列4があり、B(4, 4) に*がある。エが残る。
  5. 念のため形も確認する:Aの一番上の行(0行目)が、Bの一番右の列(7列目)になっている。これは時計回り90度の回転の形。

答え:エ(B(j, 7−i) ← A(i, j))。目立つ点を1〜2個選び、選択肢の式に代入して絞り込む。

例題 4

a(a(1,1)×2, a(2,2)+1) の値

2 次元の整数型配列 a の各要素 a(i,j) の値は,2i+j である。このとき,a(a(1,1)×2,a(2,2)+1) の値は幾つか。

ア 12
イ 13
ウ 18
エ 19

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

解き方と答えを見る
  1. a(i, j)=2i+j なので、内側から計算する。a(1, 1)=2×1+1=3。
  2. a(2, 2)=2×2+2=6。
  3. 外側の添字は、行が a(1,1)×2=3×2=6、列が a(2,2)+1=6+1=7。
  4. a(6, 7)=2×6+7=12+7=19。

答え:エ(19)

例題 5

複利の利息早見表でB4に入れる式

表計算ソフトを使って,元金千円当たりの複利による利息早見表を作成する。セル B4 に入れる式はどれか。ここで,セル B4 の式は,B4〜F13 の範囲の各セルに複写される。
表計算シート(列 A〜F,行 1〜13)
ABCDEF
1元金1,000
2利率0.020.0250.030.0350.04
3年数
41
52
63
⋮⋮⋮⋮⋮⋮⋮
1310

ア $B$1*((1+$B2)^$A4-1)
イ $B$1*((1+$B2)^A$4-1)
ウ $B$1*((1+B$2)^$A4-1)
エ $B$1*((1+B$2)^A$4-1)

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

解き方と答えを見る
  1. 複写したときに何を固定するかを整理する。元金 B1 はどこへ複写しても同じセル → $B$1(行も列も固定)。
  2. 利率は2行目に横に並んでいる。右へ複写したら列は変わってほしく、下へ複写しても2行目のまま → B$2(行だけ固定)。
  3. 年数はA列に縦に並んでいる。下へ複写したら行は変わってほしく、右へ複写してもA列のまま → $A4(列だけ固定)。
  4. 式は $B$1*((1+B$2)^$A4−1) でウ。検算:B4 = 1000×(1.02^1−1)=1000×0.02=20。
  5. C5 に複写すると $B$1*((1+C$2)^$A5−1) となり、1000×(1.025^2−1)=1000×0.050625=50.625。利率2.5%・2年の利息になっていて正しい。

答え:ウ($B$1*((1+B$2)^$A4−1))

要点(試験直前に読む)

  • 流れ図の「A → B」も擬似言語の「B ← A」も、矢印の先に値が入る。
  • 後ろへずらすときは大きい添字から。前から動かすと、まだ移していない値が上書きされて消える。
  • 連結の後半は Z(前半の長さ+k)。XとYを連結するなら Z(m+k)。
  • 2次元配列の回転は、目立つ点を1〜2個選んで選択肢の式に代入すると絞り込める。時計回り90度は B(j, 7−i)。
  • 値が式で決まる配列は内側のカッコから計算する(例:a(6, 7)=2×6+7=19)。
  • 表計算の$は直後を固定する。横に並ぶ見出しは B$2(行固定)、縦に並ぶ見出しは $A4(列固定)。

ひっかけ

  • 代入の向きが逆の選択肢:「TANGO[n−i] → TANGO[i]」のように、入れる側と入れられる側が逆になっている。矢印の先が書き換わる側かを確認する。
  • 添字に n−i が入った選択肢:一見それらしいが、i=n−1 を代入すると TANGO[1] へ飛ぶなど、隣へずらす動きにならない。具体例で1回代入すれば見破れる。
  • 連結のオフセットを n+k にする選択肢:後ろの長さで位置をずらすと、前半の末尾を上書きするか隙間ができる。m=3, n=2 などの小さな例で確かめる。
  • 回転と転置・反転の式を並べる選択肢:1点だけでは2つ残ることがある(2019年の問題では、1点目でイとエが残った)。2点目で必ず確かめる。
  • 表計算で行固定と列固定を逆にする選択肢:$B2 と B$2 の取り違え。「右へ複写したとき、この見出しの列は変わってほしいか」を1つずつ自問する。

用語(15)

配列 はいれつ
同じ種類のデータを番号付きで並べて入れておく入れ物。
添字(要素番号) そえじ(ようそばんごう)
配列の中で何番目の要素かを表す番号。
⚠ 0から始まる配列と1から始まる配列がある。問題文の「要素番号が0から始まる」などの記述で確認する。
代入 だいにゅう
変数や配列の要素に値を入れること。
⚠ 流れ図の「A → B」と擬似言語の「B ← A」は同じ意味。どちらも矢印の先が書き換わる側。
ループ端の繰返し指定 るーぷたんのくりかえししてい
「変数名:初期値, 増分, 終値」の形で、変数をいくつから始め、いくつずつ変え、いくつで終えるかを示す書き方。
⚠ 増分が −1 なら減らしていく(降順)。初期値と終値の大小だけで向きを判断しない。
シフト(ずらし) しふと
配列の要素を1つずつ前または後ろの位置へ移すこと。
⚠ 後ろへずらすときは大きい添字から、前へ詰めるときは小さい添字から処理する。逆にすると値が上書きされて消える。
退避 たいひ
上書きで消えないように、値を一時的に別の場所へ避難させておくこと。
連結 れんけつ
2つの文字列や配列をつないで1つにすること。
オフセット offset
基準の位置から何個分ずらすかを表す数。
⚠ 連結では、前に置いた並びの長さがオフセットになる。後ろの並びの長さと取り違えない。
2次元配列 にじげんはいれつ
行番号と列番号の2つの添字で要素を指す、表の形の配列。
⚠ A(i, j) は i が行、j が列。入れ替えると別の要素になる。
転置 てんち
2次元配列の行と列を入れ替えること。B(j, i) ← A(i, j) の形。
⚠ 回転は B(j, 7−i) のように「7−」が付く。付かなければ転置。
回転(90度回転) かいてん
2次元配列の図形を90度回すこと。時計回りなら B(j, 7−i) ← A(i, j)(8×8の場合)。
⚠ 反転は片方の添字だけ「7−」にする(B(i, 7−j) など)。行と列の入れ替えが無い点で回転と違う。
相対参照 そうたいさんしょう
式を複写すると、参照するセルも同じ方向・同じ距離だけずれる参照の仕方。
⚠ 絶対参照は複写してもずれない。$が付いているかどうかで見分ける。
絶対参照 ぜったいさんしょう
$B$1 のように行と列の両方に$を付け、複写しても同じセルを指し続ける参照の仕方。
⚠ 片方だけ$なら複合参照。
複合参照 ふくごうさんしょう
$B2(列だけ固定)や B$2(行だけ固定)のように、行か列の片方だけを固定する参照の仕方。
⚠ $は直後の記号を固定する。$B2 は列Bを固定、B$2 は行2を固定。
複写 ふくしゃ
表計算でセルの式を別のセルへコピーすること。相対参照の部分は位置に合わせてずれる。

このレッスンの過去問

このレッスンで稽古する