VB.NET2005 TIPS / 理数系 |
S0001 数式処理 |
最終更新:2006/11/12 再掲 |
●解説
数学的なアプリでは、プログラムで与えられた数式だけではインタラクティブな処理ができなく、ユーザに任意の数式を入力させ、処理できる必要がある。これは一見簡単そうであるが実は相当に難しい処理となる。
数学の数式の記法には大きく三つある。内挿記法(Infix Form)、前置記法(Prefix Form)、後置記法(Postfix
Form)である。内挿記法が一般に使用されている見慣れた表現方法で、オペランドにオペレータが挟まれたもの。後置記法はオペレータがオペランドの後に置かれる方法で、逆ポーランド法などと呼ばれている。
実は、人間に分かりよい内挿記法はコンピュータにとってはこの上もなく都合の悪い方法で、処理が困難となり、前/後置記法がコンピュータ向きなのである。関数電卓で逆ポーランド法のものがあるがこのためである。
・内挿記法: A+B*C 人はB*Cを先に計算し、Aに足すと直ぐに分かる。これは、高度なパターン認識。
・後置記法: ABC*+ オペレータが現れたらその前の二つのオペランドをそのオペレータで計算する。機械的にできる。
ここでは、任意の数式を逆ポーランド法による数式表現に変換する方法を紹介する。変数、定数、常数(πのみ)、リテラル(数値)、演算子、関数、括弧など、通常数式に使用できるものを扱えるものである。
Sin(3*X+6)+Cos(Y^2+1)/(A+5) 定数を含む陰関数の例
などである。後置記法の数式があれば、それを元に演算も可能となる。
●原理
オペランド、オペレータ(数学関数含む)などの因子に優先度を与え、因子をスタッキング(FILO)しながら優先度に従って、以下のように順序を入れ替えてゆく。リカーシブ処理向きであるが、処理時間節約のためループ処理方式とする。
- 出力スタックと一時スタックを置く。
- 因子を文字列から取り出す。
- その因子が一時スタック最上部の因子の優先度より低いか等しい間は、一時スタック最上部の因子を出力スタックに積む。
- 取り出した因子を一時スタックに積む。2.から繰り返す。
- 文字列がなくなったら、一時スタックに残っている因子を上から取り出して、全て出力スタックに積む。
- 出力スタックが後置記法の数式となっている。底から上の順。
数式 : A+B*C
優先度 : A、B > * > +
として、処理の流れの具体例を下に示す。下図も参照。
- Aを文字列から取り出す。最初なので、一時スタックに積む。
- +を文字列から取り出す。+はAより優先度が低いので、Aを出力スタックに移動し、+を一時に積む。
- Bを文字列から取り出す。Bは+より優先度が高いので、一時に積む。
- *を文字列から取り出す。*はBより優先度が低いので、Bを出力スタックに移動する。一時の最上部は+となるが、*の優先度が高いので、*を一時に積む。
- Cを文字列から取り出す。Cは*より優先度が高いので一時に積む。
- 文字列が終わったので、一時に残っている内容をラストアウトで出力に移す。
●仕様
○数式仕様
形式:等号、不等号を含まない式。陽関数、陰関数、定数/数値項のみなど可能。
使用文字:半角/全角。大文字/小文字。など何れでも良い。混在も可能。
間隔:任意数のスペース
以下は因子となる
括弧:(、)
変数:X、Y
定数:A、B、C、D、E を使用できる。
常数:PI (πのこと)
数値:数字と小数点
(単純)演算子:+、-、/、*、^
関数:Rad、Abs、Sqrt、Sin、Cos、Tan、Exp、Log、Ln (関数の引数は必ず()で括る)
Rad(式) は、度を表す式をラジアンにする関数
○優先度
処理の優先度は以下の通り。番号の大きいものがより優先度が大きい。スペースは処理時無視される。
0:)
1:+、-
2:*、/
3:^
4:関数
5:変数、定数、数値
6:(
○演算子仕様
単項演算子 : +Aの+は無視する。-A は、0 - A と解釈する
単純演算子: 連続できない A/-5 はエラーとなる。A/(-5)はOK。
A op B、(式) op (式) : opは、+-*/^
関数 : 関数(A)、関数(式)
式 : 上記で構成された数式
●方法
以下のような処理方法、手順となる。
原理の説明例では因子は一文字であったが、実際には、複数文字(関数、常数、数値)もあるので、原式(原文字列)から因子を分離した文字配列(因子列)を生成し、処理する。
-
原式から全てのスペースを除去する。
-
全て半角、小文字にする。
-
許可された文字かどうかチェックする。→エラー
-
括弧の整合性をチェックする。→エラー
-
因子毎に分離し、因子列を生成する。(原理で説明した数式文字列に相当)
・因子の識別を行う。→エラー
・因子間の関係や文法が正しいかチェックする。→エラー
・因子の優先度を決める。
-
出現した変数や定数のテーブルを生成する。
-
このクラスに於ける標準の内挿表現形式の原式を生成。
-
因子列を後置記法に変換する。
●実例
|