アルゴリズムとフローチャート

1、計算機とアルゴリズム

 

 計算機は非常に強力なツールで、現代社会において非常に有益な機器であり、様々な分野において必要不可欠なものとなっています。元々は、大砲の弾 がどのように飛ぶかを計算するために開発されました。しかし、現在ではただ単に単純な計算をするだけでなく、多くの分野で利用されています。

 

 計算機は、単純な演算を高速で行うことによって、決まりきった仕事を成し遂げる機械である。行う演算は単純なもの(例えば、2数の加算や比較など の演算)でしかないが、演算速度がきわめて高速(1秒間に100万回程度)であるために十分にその欠点を補うことが出来る。すなわち、多くの演算を高速に 行うことによって、かなりの規模の仕事をこなすことができます。

 計算機では、機械で実行できる単純な演算を用いて指示される仕事しか行うことが出来ません。また、計算機で仕事を行うためには、計算機がどの演算 を行うのかを指定しなくてはなりません。言い換えると、仕事をどのようにして行うのかを記述しなければないません。このような記述のことをアルゴリズム(algorithm)といいます。アルゴリズムとは、仕事を行う処理手順を1ステップずつ順に並べたもので、それらがまとまって1つの問題の解法を作ります。アルゴリズムは一連のステップからなっていて、それぞれを忠実に成し遂げることによって、仕事、すなわち一つの処理プロセス、process)を達成することが出来ます。一般に、アルゴリズムのことを問題の処理手順という意味で解釈されています。

 

 アルゴリズムの概念は、計算機科学に特有のものというわけではなく、日常生活における多種多様の処理を表すアルゴリズムも存在します。例えば、ご 飯の炊き方や車のパンクの修理の仕方などがある。ましてやフランス料理などの手の込んだ料理の手順などは、非常に細かなものとなる。コンピューターで実行 されるプログラムもある変数に1を加えたり、あるいはある変数から別の変数の値を引いたりすることによって成り立っている。従って、アルゴリズムはコン ピューターの分野にだけ存在するものでなく、われわれの日常生活にも存在し、また特殊な分野においてもアルゴリズムは存在する。例えば、自動車工場などの 塗装ロボットなどの制御においてもアルゴリズムは存在する。

 

 一般に処理を実行する担い手のことをプロセッサ(processer)といいます。プロセッサは人であったり、計算機であったり、あるいは電子的・機械的な装置であったりします。プロセッサは、処理を記述しているアルゴリズムに従い、それを実行する(execute)ことにより仕事を成し遂げる。アルゴリズムを実行するには、そのアルゴリズムを構成している個々のステップを実行することになります。

 

 ある目的を達成するためのアルゴリズムは必ずしも1つとは限りません。アルゴリズムによっては目的を達成するために要する時間が短かったり、また は長かったりしたり、あるいは手順が少し入れ替わったりすることもあります。アルゴリズムを作成する場合、アルゴリズムの効率を考えることも重要なことで すが、最もわれわれが考えなければならないことは、アルゴリズムを利用する側、つまりプログラムを利用するユーザーだけでなく、保守開発するプログラマに とっても有益であるかということです。

 

 アルゴリズムを表現する方法には様々なものがあります。例えば、文章でアルゴリズムを記述したり、図で考えを表したりします。この場合、アルゴリ ズムを文章だけで表したりすると誤解を生じ、正確にその考えを伝えることができない場合が多い。アルゴリズムを最も正確に表す方法として、流れ図(フロー チャート)があります。流れ図は、JIS規格で定められた流れ図記号を用いて作成します。通常、流れ図はプログラムを作るときの指針となるものですので、 プログラムを作る前にアルゴリズムを作成します。

 

2 良いアルゴリズムとは?

 

 ある問題を解くためのアルゴリズムは複数存在します。それらの中から最適なアルゴリズムを見つけることは、情報処理技術者にとって重要なことです。良いアルゴリズムの条件としては次のようなものがあります。

  1. 信頼性が高いこと
  2. わかりやすいこと
  3. 一般性があること
  4. 拡張性があること
  5. 効率が良いこと

 アルゴリズムの信頼性は、非常に重要な条件です。一般的に信じられていることに反して、計算機が間違うことはほとんどありません。もっとも、動作 しなくなったり、結果的に間違った答えを表示することは良くあります。これは、計算機が間違えたわけではなく、ほとんどの場合が実行されたアルゴリズムに 欠陥があるためであるか、入力データが間違っているために生じることである。

 

 計算機は、ある意味ではまったく従順な奴隷と同じである。与えられたアルゴリズムを忠実に実行し、必要ならば、不平を言うことなく何度でも繰り返して実 行します。そのような忠実さは長所であるが、短所でもあります。計算機は、アルゴリズムが意図した処理を正しく記述しているかどうか関係なく、そのアルゴ リズムを実行します。

 

 アルゴリズムの分かりやすさは、明瞭性と簡潔性の2点に集約できます。明瞭性とは、プログラムを人間にもマシンにも分かりやすく書くことを表します。簡潔性は、プログラムを短く扱いやすい状態にしておくことということです。

 

 アルゴリズムの一般性は、すべてのアルゴリズムにおいて必要とされるわけではありません。幅広い状況できちんと機能し、新たな状況にもうまく対応できることです。

 

 アルゴリズムの拡張性は、・・・

 

 効率が良いことは、・・・

 

3 プログラムとプログラミング言語

 

 計算機を多くの分野で利用するためには、それぞれの目的に適した動作をコンピューターに教える必要があります。つまり、適切なアルゴリズムをコンピューターに与える必要があります。計算機に対するアルゴリズムをプログラムと呼びます。

 コンピューターを動かすためには、コンピューターが理解できる特別な言葉を使わなければなりません。この言葉を、プログラミング言語といいます。また、アルゴリズムをプログラムとして表現することをプログラミングといいます。プログラミングについては、プログラミング入門というページがありますので興味のある人は参照してください。

 

3.1 プログラムの基本構造

 

 プログラムの基本構造について簡単に説明してみましょう。プログラムはコンピュータにさせたい仕事が順番に書かれていて、コンピューターが読める 形にもなっています。通常、プログラムは横書きで、テキストの上から下に向かって書いて行き、コンピュータもそれを上から下に向かって実行して行きます。

 例えば、“ロボット”というプログラム可能なロボットがいたとします。“ロボット”に”お茶を煎れさせるプログラム”を書くと次のようになります。

  1. お湯を沸かせ
  2. 湯呑みを用意しろ
  3. きゅうすに茶っぱを入れろ
  4. きゅうすから湯飲みに注げ

 この順番が間違っていると、コンピュータは正しく動作しません。場合によっては、“暴走”します。一番最初に「きゅうすから湯飲みに注げ」があったら、“ロボット”は、入ってもいないお茶を、ありもしない湯飲みに注ごうとして、結局、お茶を入れることが出来ません。

 

 “ロボット”が有能で、“お湯を沸かせ”と言われただけでお湯を沸かせればいいのですが、“お湯を沸かす”ということ自体をプログラムする必要がある場 合もあります。そういう時には、“お茶を煎れさせるプログラム”と同時に、“お湯を沸かさせるプログラム”が必要になります。

  1. やかんに水を入れろ
  2. やかんをガステーブルに置け
  3. ガステーブルを点火しろ
  4. しばらく待て
  5. 沸騰したら火を止めろ

 “お湯を沸かさせるプログラム”の中には、“やかんに水を入れるプログラム”や“やかんをガステーブルに置くプログラム”が必要です。“お茶を煎 れさせるプログラム”から見ると“お湯を沸かさせるプログラム”は下請で、“やかんに水を入れるプログラム”はそのまた下請(孫請)ということになりま す。プログラムはこのように“下請の下請の下請の...”という具合の階層構造になります。

 

 “お茶を煎れさせるプログラム”はそういう意味では、

  1. お湯を沸かすプログラムを実行する
  2. 湯呑みを用意するプログラムを実行する
  3. きゅうすに茶っぱを入れるプログラムを実行する
  4. きゅうすから湯呑みに注ぐプログラムを実行する

というプログラムになります。

 

 このようなプログラムの階層構造では、“プログラムで何ができるか”は“どんな下請を使えるか”で決まります。させたいことをやってくれる下請が ない場合は、まずその下請プログラムを作る必要があります。下請プログラムもまた、その下請としてどんな下請を使えるかで何ができるのかが決まります。そ うやって、どんどん下に向かって“何ができる?”と追求して行くと、最後にはコンピュータの基本機能に行き当たります。

 

3.2 プログラミング言語における基本要素

 

 プログラミング言語の基本的な構成要素としては、だいたい次のようなものがあります。

  • 変数
  • 演算子
  • 関数(または命令)
  • 制御文

3.3 変数

 

 プログラミング言語では、たいていどんな言語でも“変数”を使います。Y = 2x なんていう式の Y や x が“変数”になります。変数はその名の通り、値が変えられる数のことで、簡単に言うと、数値を入れておく箱のことです。

 コンピュータのハードウェアの中枢は、おおざっぱに言ってしまえば演算(計算)をするCPUと、値(データ)を保持するメモリから成り立っていま す。メモリは作業中にデータを入れておく箱のようなもので、一つの箱には1バイトのデータを入れることができます。一時的な置場所なので、その時その時に よって入っている値が変わります。これを“変数”だと考えると、人間にとってメモリというものを扱いやすくなります。

 

3.4 演算子

 

 演算子というのは、+ - × ÷ などの計算用の記号のことです。プログラミング言語ではたいていの場合、+ - × ÷  (四則演算子)は + - * / を使います。

 

 プログラミング言語で独特な演算子として、“代入演算子”があります。これは、たいていの場合“=”(イコール記号)を使います。PASCALなどでは“:=”を使いますが、これから先、プログラミング言語の例などは C 言語を想定して、話を進めたいと思います。C 言語では“=”を用います。

 

 算数では、y = 2x と書くと、“yと2xが等しい”という意味になります。これは、イコール記号が“等号”として使われているからです。プログラミング言語で等号としてではなく、“代入演算子”として使うと、同じように y = 2x と書いた場合は、“yに2xを代入する”という意味になります。結果としては両辺がイコールになるのですが、“=”が代入演算子であるという、特徴的な使われ方を紹介しておきます。

 

 y = y + 1

 

 “=”が等号のとき、これはあり得ない式です。が、代入演算子の場合は“yの内容を今までのyの値より1大きい値にする”という意味になります。

 

3.5 関数と命令

 

 関数や命令というのは、前回触れた「下請プログラム」のことです。プログラムを作成する上では、数々の下請けプログラムを使いますし、自分でも作ることになります。

 

 “命令”といわれるものは、複数の細かい命令が組み合わされて、あらたな名前を定義したものです。前回の例でいうならば「お湯を沸かせ..」からの一連の処理をまとめて「お茶を煎れろ」という新しい命令を作るわけです。

 

 “関数”といわれるものは、引数を渡して結果を返してもらうタイプの下請けプログラムです。例えば「数字を渡すとその数を2倍して返してくれる関数」を“bai”という名前で作るとき、C言語では

 

int bai(int su) /* su は引数(渡される値)*/
{
    return su*2;
}

 

などと書きますが、これを使う側のプログラムでは、

 

int x;
int y;
x=5;
y=bai(x);    /* x は引数(関数に渡す値)*/

 

ってな具合に使います。この例は、関数にする必要がない簡単な例ですが、仮に関数baiが、どんなに複雑な処理を行う関数だったとしても、使う側のプログラムではまったく変わりなく、1行で y=bai(x); とするだけですみます。

 

 ここで行っている“下請けプログラム”は、言語によっては“サブルーチン”と呼ばれたりもします。また、その言語にもともと備わっている命令や関 数を“命令(コマンド)”“関数(ファンクション)”と呼び、プログラマが自分で作る下請けプログラムを“サブルーチン”という場合もあります。C言語で は、それらは全部ひとまとめにして“関数”と言い、命令か関数かという違いもありません。上記の説明でいう“命令”はC言語では“戻り値のない関数”とし て実現されます。

 

 “制御文”というのは、プログラムの流れを記述するためのものです。前回の冒頭に「プログラムは下に向かって順番に実行される」という原則を書き ましたが、その原則だけではごく簡単な処理しかできません。そこで制御文を使ってプログラムの流れを変化させます。制御文の代表格として“条件分岐”と “繰り返し(ループ)”があります。

 

3.6 条件分岐

 

 プログラムでは、計算の結果や渡された引数の値によって、違った処理を行いたいことが多々あります。条件分岐の制御文で最も広く種々の言語で用いられているものとして、IF文があります。言語によって文法や用法に多少の違いはありますが、

 

IF (条件)
    条件が真(True)だった場合の処理
ELSE
    条件が偽(False)だった場合の処理
END IF

 

といった記述をします。“条件”にはたいていの場合、論理式が用いられます。論理式というのは、その式があっているか、間違っているかを返す式です。例えば、(2 = 5)という式は間違っているので“偽(False)”を返します。(注意:C言語では前回の説明のように、“=”は代入演算子なので(2 == 5)と書きます。)(10 <100)という式は正しいので“真(True)”を返します。

 

 条件分岐には、IF文のほか、複数条件に対応できるものが各言語で用意されています。例としてC言語のswitch文を掲げておきます。

 

switch(値)
{
    case 1:
        値が1だった場合の処理
        break;  /*もうこれ以上判断しない(switch文を抜ける)*/
    case 2:
        値が2だった場合の処理
        break;
    default:
        値がそれ以外だった場合の処理
}

3.7 繰り返し

 

 プログラムの中では、同じ処理を何度も行いたいことも多々あります。同じ記述を何度もするのは無駄ですし、見た目にもわかりにくいプログラムに なってしまいます。また、修正も大変になります。そこで、各言語には繰り返し処理のための制御文が用意されています。繰り返し文の代表格はFOR文で、や はり多少の違いはありますが、多くの言語に採用されています。例としてC言語のfor文を掲げます。

 

for ( (カウンタ初期値) ; (条件) ; (カウンタ更新式) )
{
    処理
}

 

 カウンタというのは“何回繰り返したか”を数えるためのもので、たいていの場合変数を用います。カウンタ初期値は、カウンタの始まりの値を代入文 で記述します。条件はIF文と同じ論理式で、この論理式が“真(True)”を返している限り、繰り返されるようになっています。カウンタ更新式は、一度 の繰り返しごとに実行され、カウンタの値を変化させるための式です。抽象的でわかりにくいので、1から100までの数字を足して、結果を変数Bに入れるプ ログラムの例を参照して下さい。この例では、カウンタとして変数Aを使っています。

 

 

int A;
int B;
B = 0;
for( A = 1; A <= 100; A="A" + 1)
{
    B = B + A;
}


 

【上記プログラムの解説】

カウンタ初期値 A = 1; (Aは1から始める)
条件 A <= 100; (A が 100以下かどうかにより、真/偽を返す)
カウンタ更新式 A = A + 1; (Aの値を1増やす)
処理 B = B + A; (BにAの値を加算する)
(条件が真だったら、カウンタ更新式を実行して処理を繰り返す。偽だったら FOR 文を抜ける)

なおC言語の独特な書き方として、A = A + 1は A += 1 とか A++ と書くこともできます。

 

4 フローチャートって何ですか?

 

 問題を処理する考え方(アルゴリズム)を図的表現したものをフローチャートという。フローチャートはプログラムを作成するときに必要なものであり、さらに後でプログラムを保守するときにも必要なものである。

 

 フローチャートを用いることにより、プログラムの流れを正確に把握でき、第3者にも伝えることが可能となる。

 

 フローチャートが書けるということは、与えられた問題を分析し、理解できたということにつながる。これは優秀なプログラマになるための第一歩である。

 

5 フローチャートの例

 

例) 変数 x をキーボードから入力して、その絶対値を表示する。

 

6 フローチャートの基本的な約束事

 

6.1 初めと終わり(入り口と出口)

 

 プログラムに始めと終わりがある。フローチャート記号ではこの始めと終わりを端子記号で書く。端子記号の中には「開始」または「終了」、「start」または「end」と書く。処理の手順により、終了は複数存在してもよい。

6.2 処理の流れ

 

 処理の流れは線記号で表現され、流れの方向は原則的には左から右へ、上から下であるが、場合によっては逆方向に流れることもある。よって、処理の流れが左から右、上から下以外の場合は線記号に矢印を付けて進む方向を明示しなければならない。

 フローチャートは誰が見ても容易に理解でき、正しい論理で簡潔に書かれていることが望ましい。また、誤解の余地がないように、丁寧に分かりやすく 綺麗に書くようにする必要がある。処理が複雑になると線記号が交差してしまうことがある。このような時には、記号の配置を変更して分かりやすく書く。

 

6.3 入力と出力

 

 入力と出力は次の記号で書く。入力の場合は、入力する値の格納先となる変数名を書く。出力の場合は、値を出力する変数の名前や式を書く。

6.4 代入

 

 変数に値を代入する処理は次のように書く。すなわち、← の左辺に代入先の変数を書き、右辺に代入する値(定数、変数または式)を書く。

6.5 判断・分岐

 

 処理の流れの中で、条件によって次に行う処理が変わるとき、判断記号を用いる。判断は1つ入り口といくつかの出口を持ち、入り口は上の頂点を、出 口はほかの頂点をとして書く。記号の中には判断の条件(条件式)を書く。出口と次の処理は線記号で繋ぎ、1つの頂点から延びる線は1本とする。さらに、頂 点付近に条件が成立したときには、「Yes」、「Y」または「はい」と書き、条件が成立しなかったときには、「No」、「N」 または 「いいえ」 と書く。

 判断の書き方はいくつかの方法がある。理解しすく誤解を招かないように、誰が見てもわかるように書く必要がある。

6.6 フローチャートの表現

 

 フローチャートの記号を書く道具として、流れ図定規(テンプレート定規)がある。通常、kのテンプレート使って書く。記号の大きさや、縦横の比な どの制約はなく、記号の形が約束事あに会っていれば良い。自分の都合の良い大きさに合わせて柔軟性に書くことができる。MS-Word でがフローチャート記号を手軽に欠ける機能があり、これらを使っても良い。

 

7 フローチャートの基本的な記号

 

8 フローチャートを書

 

 

 

9 フローチャートの基本構造

 

 

 

参考文献

  1. L. ゴールドシュレーガー、A. リスター、計算機科学入門 第2版、近代科学社、1987
  2. R. ファイマン、ファイマン計算機科学、2000
  3. B. W. カーニハン、R. パイク、プログラミング作法、アスキー出版、2000
  4. 林 正幸、図解 アルゴリズム入門、共立出版株式会社、1992