テクノロジ系

アルゴリズムとプログラミング 重点教科書

アルゴリズム問題は知識ではなく「トレース力(処理を1行ずつ追う力)」で解きます。焦らず表を書いて変数の値を追跡すれば必ず解けます。まずはデータの持ち方(データ構造)から見ていきましょう。

1. データ構造

プログラムを作るとき、データをただバラバラに持っておくのではなく、「どういう順番で」「どういう形で」保存しておくかを工夫すると、後で扱いやすくなります。この工夫の仕方をデータ構造と呼びます。

まず基本になるのが、変数やフィールドといった「データを入れておく箱」の考え方です。1つの値だけを入れる箱を並べて管理するのが配列、関連するいくつかの項目をひとまとめにしたものがレコード、そのレコードをたくさん集めたものがファイルです。たとえば、名簿を思い浮かべてください。「氏名」「電話番号」「住所」という項目をひとまとめにしたものが1人分のレコードで、それをクラス全員分集めたものがファイルにあたります。

こうした基本の上に、目的に応じたいくつかの代表的なデータ構造があります。

リストは、データを一列に並べて管理する構造です。順番に意味があり、途中にデータを追加したり削除したりしやすいのが特徴です。

キューは、「先に入れたものから先に取り出す」という規則(先入れ先出し、FIFO)を持つデータ構造です。これは、レジやチケット売り場の行列とまったく同じ仕組みです。先に並んだ人から順番に処理されていき、後から来た人は列の最後尾に並びます。プログラムの中でも、処理の順番を待たせておく場面(印刷待ちの書類が順番に処理されるプリンターの仕組みなど)でキューが使われます。

スタックは、逆に「後から入れたものを先に取り出す」という規則(後入れ先出し、LIFO)を持つデータ構造です。お皿を積み重ねていくところを想像してください。一番上に置いたお皿(最後に積んだお皿)から順番に取っていくのが自然でしょう。ブラウザの「戻る」ボタンを押すと直前に見ていたページに戻るのも、スタックの考え方が使われている身近な例です。

木構造は、データを枝分かれさせながら階層的に整理する構造です。会社の組織図や、パソコンのフォルダとサブフォルダの関係を思い浮かべるとイメージしやすいでしょう。1つの親の下に複数の子がぶら下がる形で、データ全体を効率よく整理・検索できます。木構造の中でも、1つの親要素の下に子要素が最大2つまでしかぶら下がらないものを2分木と呼びます。2分木は特にデータの検索や並べ替えの処理と相性がよく、次章の探索アルゴリズムとも深く関わっています。

リスト・キュー・スタック・木構造の違いを示す比較図
リスト・キュー・スタック・木構造の違いを示す比較図

2. アルゴリズムとプログラミング

「アルゴリズム」と聞くと難しそうに感じるかもしれませんが、実はとてもシンプルな考え方です。アルゴリズムとは、ある問題を解決するための「手順」のことです。カレーライスの作り方のレシピが「野菜を切る→炒める→煮込む→ルーを入れる」という手順で示されているように、コンピュータに何かをさせるときも、明確な手順として表現する必要があります。

アルゴリズムの基本構造——3つの型を組み合わせる

どんなに複雑なアルゴリズムも、実は3つの基本構造の組み合わせでできています。順次は、書かれた手順を上から順番にそのまま実行することです。レシピを最初の行から順にこなしていくのと同じです。選択は、ある条件によって処理を分岐させることです。「もし焦げそうになったら火を弱める」というように、状況に応じて別の手順に切り替える構造です。繰返しは、同じ処理を条件が満たされるまで何度も実行することです。「よく混ざるまでかき混ぜ続ける」という指示がこれにあたります。この3つの型を組み合わせるだけで、どんなに複雑な処理も表現できるのです。

アルゴリズムの表現方法——図と疑似言語

アルゴリズムを人に伝えたり、後で見返して確認したりするためには、決まった書き方で表現する方法が使われます。矢印や図形を使って手順を視覚的に表す流れ図(フローチャート)と、プログラム言語に近い書き方をしつつも特定の言語には縛られない擬似言語が代表的です。

擬似言語やプログラムの中では、いくつかの共通した部品が登場します。計算を行う、正しいか間違っているかを判定する条件式、計算に使う記号である演算子、変数に値を入れる代入、プログラムの説明を書き添える注釈(コメント)、データの出し入れを行う入出力などです。また、いくつかの処理をひとまとめにして名前をつけたものを手続関数と呼び、それらに渡す値を引数、処理結果として返ってくる値を戻り値と呼びます。扱うデータの種類(整数を扱う整数型、小数を扱う実数型、真か偽かを扱う論理型、文字を扱う文字型など)をデータ型と呼び、あらかじめ決めておくことでコンピュータが正しくデータを扱えるようになります。

代表的なアルゴリズム——探すアルゴリズムと並べるアルゴリズム

多くのデータの中から目的のものを見つけ出す探索のアルゴリズムには、代表的なものが2つあります。線形探索法は、先頭から順番に1つずつ確認していく方法です。電話帳を最初のページから1件ずつめくって目的の名前を探すようなイメージで、確実ですがデータが多いと時間がかかります。一方2分探索法は、あらかじめ順番に並んでいるデータに対して、真ん中の値と目的の値を比べ、大きいか小さいかによって探す範囲を半分に絞り込んでいく方法です。電話帳で「あ行」か「な行」かをまず見当をつけ、さらに範囲を絞り込んでいくようなイメージで、データが多いほど線形探索法より圧倒的に速く目的のものにたどり着けます。ただし2分探索法は、データがあらかじめ並べ替えられていることが前提になります。

複数のデータをある順序に並べ替える整列(ソート)のアルゴリズムも重要です。選択ソートは、まだ並べていない範囲の中から一番小さい(あるいは大きい)値を見つけて、先頭から順に確定させていく方法です。バブルソートは、隣り合う2つの値を比較して、順序が逆であれば入れ替えるという操作を繰り返しながら、大きな値を少しずつ端に押し出していく方法です(水中で泡が浮かび上がっていく様子に似ていることからこの名前がついています)。クイックソートは、基準となる値(ピボット)を決めて、それより小さいグループと大きいグループに分割することを繰り返しながら並べ替えていく方法で、一般に大量のデータに対して高速に動作します。

そして併合(マージ)とは、すでに並べ替えられている複数のグループを、順序を保ったまま1つにまとめる操作のことです。

プログラミングとは

こうして考えたアルゴリズムを、実際にコンピュータが実行できる形に書き起こす作業がプログラミングです。プログラミングによって、私たちが考えた手順(アルゴリズム)を、プログラム言語という「コンピュータにも人間にも読める言葉」を使って記述し、コンピュータ上で実際に動かせるようになります。試験でアルゴリズムの問題を解くときは、いきなり正解を探そうとせず、変数の値がどう変化していくかを紙に書き出しながら1行ずつ手順を追う「トレース」という作業を行うと、正確に解けるようになります。

線形探索と2分探索の比較図
線形探索と2分探索の比較図

3. プログラム言語

アルゴリズムを実際にコンピュータで動かすには、プログラム言語で記述する必要があります。プログラム言語にはさまざまな種類があり、それぞれ得意な分野や特徴が異なります。

代表的なプログラム言語として、古くから科学技術計算に使われてきたFortran、汎用性が高く長年にわたり大規模なシステム開発で使われてきたJava、Javaのもとになった高速な処理が可能なC、Cにオブジェクト指向の考え方を取り入れて拡張したC++、文法がシンプルで初心者にも読みやすくAI・データ分析の分野でも広く使われているPython、Webサイトに動きをつけるために生まれ現在ではさまざまな用途に使われるJavaScript、統計解析やデータ分析に特化したRなどがあります。プログラムを書く目的に応じて、これらの言語から適切なものを選ぶことが重要です。たとえばWebサイトに動きをつけたいならJavaScript、データ分析をしたいならPythonやR、というように使い分けられています。

プログラムを書く際には、複数人での開発や後からの見直しをしやすくするための工夫も欠かせません。コーディング標準は、プログラムの書き方に関するルールの取り決めのことで、これに従うことで誰が読んでもわかりやすいプログラムになります。具体的には、階層構造を見やすくするために行の先頭に空白を入れる字下げ(インデンテーション)、条件分岐や繰り返しがどれくらい入れ子になっているかを示すネストの深さ、変数や関数の名前のつけ方のルールである命名規則などが挙げられます。

大きなプログラムを作るときは、全体を意味のあるまとまりに分割するモジュール分割が行われます。プログラム全体の中心となる処理をメインルーチン、そこから呼び出される個別の処理をサブルーチンと呼びます。また、すでに誰かが作った便利な機能をまとめたライブラリを活用すれば、一からすべてを作らなくても効率的にプログラミングができます。あるソフトウェアが持つ機能を、外部のプログラムから呼び出せるようにする仕組みをAPIと呼び、その中でもインターネット経由で使えるものをWebAPIと呼びます。

近年では、プログラムのコードをほとんど書かずにアプリケーションを開発できるローコードや、まったくコードを書かずに開発できるノーコードというツールも普及しています。専門的なプログラミングの知識がなくても、画面の部品をマウスで配置していくだけで簡単な業務アプリやWebサイトが作れるサービスが増えており、IT人材が不足する中で、こうしたツールの重要性はますます高まっています。

4. その他の言語(データ記述言語)

プログラム言語とは別に、データそのものの形式を表現するための言語もあります。これらは「処理の手順」を書くのではなく、「データがどんな構造になっているか」を記述するためのものです。

代表的なものがマークアップ言語です。文章の中に「タグ」と呼ばれる目印を挟み込むことで、その部分がどんな意味を持つか(見出しなのか、太字にしたい部分なのかなど)を表現します。その代表格がHTML(Hyper Text Markup Language)で、私たちが普段見ているWebページのほとんどはHTMLで組み立てられています。たとえば「これは見出しです」という意味を持たせたい文章を、開始タグと終了タグで挟むことで、ブラウザがそれを見出しとして表示してくれます。

データの意味や構造をより柔軟に表現するための言語がXML(Extensible Markup Language)です。HTMLがWebページの見た目や構造を表すのに特化しているのに対し、XMLは自分で自由にタグの名前を決めて、さまざまな種類のデータを表現できるという特徴があります。なお、HTMLやXMLのようなマークアップ言語の元になった、より古い規格としてSGMLがあります。

活用例としては、HTMLによるWebページの表現、XMLによるデータの表現(企業間でのデータのやり取りや、設定ファイルの記述など)が挙げられます。

もう1つ重要なデータ記述言語がJSON(JavaScript Object Notation)です。JSONは、データを「名前」と「値」のペアで表現するシンプルな形式で、たとえば「氏名:山田太郎」「年齢:20」のように、項目名と実際の値を対にして書き並べていきます。XMLに比べて表記がシンプルで人間にも読みやすく、また機械にとっても処理しやすいため、現在ではWebサービス同士がデータをやり取りする際の形式として非常に広く使われています。スマホアプリがサーバーと通信して情報を取得するとき、その裏側では多くの場合JSON形式でデータがやり取りされています。

HTMLとJSONの記述例の見比べ図
HTMLとJSONの記述例の見比べ図

本番での解き方

  • アルゴリズム問題は1問に時間がかかるので、模試では後回しにして最後に解く戦略も有効
  • トレースは頭の中でやらず必ず紙に表を書く。1周分書けばパターンが見えることが多い
  • 二分探索は「整列済みでないと使えない」という前提条件そのものが出題される
  • キュー(FIFO)とスタック(LIFO)は「取り出される順番」を具体例(行列・積み上げた皿)でシミュレーションする
  • HTML・XML・JSONは「何のための記法か」で区別する。JSONは名前と値のペア、というシンプルさが最大の特徴

アルゴリズムとプログラミングの過去問を解いて定着させよう

本番同様のCBT形式で無料演習。採点後は弱点に合わせた「あなた専用教科書」が作れます。

無料で過去問演習をはじめる

同じ分野の教科書