今回から数式処理に挑戦してみます。これは「数値」ではなく入力された「式」を評価し計算する処理で、文字列の処理やデータ構造などアルゴリズムの総合的な演習の題材にもってこいでしょう。今回は、その第一歩として足し算をやってみました。
足し算の式は「数値」と「演算子」で構成されます。数値を正の整数に限定すれば、式の中に出てくるのは整数とプラス記号だけという事になり、プラス記号で「区切られた」数値を順番に加算して行く事で「足し算」を実現できるでしょう。
つまり、処理のポイントは「プラス記号で区切られた数値」をどう切り分けるか、という言わばトークンに分ける処理になるわけです。今回は、区切り記号がプラス演算子だけなので、個々の数値を得るにはプラス演算子が出てくるまでの文字列を1文字ずつ拾って行き、演算子が出てきたらそれまでの文字を数値に変換すれば良いですね。数値はいくつあるかわからないので、リストに入れて行く事にしましょう。
数値を入れる連結リストクラスs2listを定義し、その変数numに数値を格納して行く事にすると式のある一字を処理する部分は以下のようになります(この処理では、文字列strのiIndex+1番目にある文字が処理される)。
switch (str.charAt(iIndex)) { // 一字取り出す case '0': // 数字なら文字列に追加 case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num+=str.substring(iIndex,iIndex+1); // 数字を文字列に追加 break; case '+': // 演算子が来たらそれまでの文字列を数値化 sl.num=Integer.parseInt(num); // 文字列を数値化しリストに保存 sl.next=new s2list(); // 次のリスト生成 sl=sl.next; num=new String(); // 文字列初期化 break; }
これで、式を見て数字なら作業用文字列に数字を溜め、プラス記号が来たら溜めておいた数字を数値に変換する部分が出来ました。後は、この処理を文字列として渡された式の先頭から最後まで順次繰り返すだけです。
・加算処理関数 int hyoka(String str) { // 数式を計算 int iIndex=0,iRes=0; String num=new String(); s2list sl,lstart=new s2list(); sl=lstart; while(iIndex<str.length()) { // 文字列の評価 switch (str.charAt(iIndex)) { // 一字ずつ取り出す case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num+=str.substring(iIndex,iIndex+1); // 数字を文字列化 break; case '+': // 演算子が来たらそれまでの文字列を数値化 sl.num=Integer.parseInt(num); // リストに数値を保存 sl.next=new s2list(); // 次のリスト生成 sl=sl.next; num=new String(); // 文字列初期化 break; } iIndex++; // 処理中済みポインタ更新 } sl.num=Integer.parseInt(num); // 最後の数値を取得 sl.next=new s2list(); sl=lstart; while (sl.next!=null) { iRes+=sl.num; // 数値のリストをすべて加算 sl=sl.next; } return iRes; // 計算結果を返す }
この関数は、簡単に言えば「演算子で区切られた数値のリストを作成し、作成したリストをすべて合計する」関数です。演算子というトークンを基に式の構成要素である数値を取得する処理、とも言えるでしょう。今回は、数値とプラス記号のみなので数値だけをリストにしましたが、数式処理は最終的には式の構成要素のリスト(というより木構造)を作成し、要素を評価していく処理になるようです。
左側の入力欄に式を入力してからGoボタンをクリックすると、右側の入力欄に結果が表示されます。ただし、エラーの確認はしていないので数字とプラス記号以外は入れないようにしてください。
トップ 戻る |