お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"括弧・演算子優先計算"

この発言に対し以下のコメントが寄せられています
#00667 J-OH!     さん 括弧・演算子優先計算/修正

◆説明◆  Edit などに入力された ((8+10/5)*2)-((20-15)*2) などという 計算式を、括弧優先・演算子優先に従って計算します。  プログラマの間では、一般的に "逆ポーランド法" が知られてい ますが、配布することを前提としたソフトでユーザー指定の式に対 してこのような処理が行われるような場合、その Readme.txt など に「・・・なお、計算式の記述は逆ポーランド法で行って下さい」 というのは、ちょっと無理があるかも知れません。 (そんなソフトないかな (^^; ) ◆使用法◆  Edit1 に計算式を入力し、その答えを Edit2 に表示させるような  場合、  Edit2.Text := MainCalk(Edit1.Text);  として御使用してみて下さい。 ◆注意◆  ・入力される計算式は、半角文字のみで、スペースは使用しない   ようにして下さい。  ・コンバートエラー等、発生しうるエラーには対応していません。 (・それ以前に、バグがあるかも知れません。 (;_;) ) ◆サンプルコード◆ unit Unit1; interface   ・   ・ type TForm1 = class(TForm)   ・   ・ private { Private 宣言 } function MainCalk(Value: String): String; // ← 記入 function SubCalk(Value: String): String; // ← 記入 public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.DFM} function TForm1.MainCalk(Value: String): String; var Moto, Moji, Frnt, Back, data: String; Stt, Max, Cnt: Integer; Fin: Boolean; begin Moto := Value; Fin := False; while Fin = False do begin Max := 0; Cnt := 0; // 最内の () のスタート位置判定 for Stt := 1 to Length(Moto) do begin Moji := Copy(Moto, Stt, 1); if Moji = '(' then begin inc(Cnt); if Cnt > Max then Max := Cnt; end else if Moji = ')' then dec(Cnt); end; // 入力データに () がある場合の処理 if Max <> 0 then begin Stt := 1; Cnt := 0; Frnt := ''; Back := ''; data := ''; { 最内の "(" の位置まで、変数 Frnt に一文字ずつ代入  しながら進む} while Cnt < Max do begin Moji := Copy(Moto, Stt, 1); if Moji = '(' then inc(Cnt) else if Moji = ')' then dec(Cnt); if Cnt < Max then Frnt := Frnt + Moji; inc(Stt); end; // 最内の () 内を計算 Moji := Copy(Moto, Stt, 1); while Moji <> ')' do begin data := data + Moji; inc(Stt); Moji := Copy(Moto, Stt, 1); end; data := SubCalk(data); inc(Stt); Back := Copy(Moto, Stt, Length(Moto)-Stt+1); { 変数 Moto に、Moto の最内の () 内だけを計算した形の  文字列を代入 } Moto := Frnt + data + Back; end else begin Moto := SubCalk(Moto); Fin := True; end; end; Result := Moto; end; function TForm1.SubCalk(Value: String): String; var Stt, Bgn: Integer; Moto, data, Moji, Kigou, Frnt, Back: String; Usen, Fin: Boolean; Fext, Bext: Extended; begin Moto := Value; Fin := False; while Fin = False do begin Usen := False; for Stt := 1 to Length(Moto) do begin Moji := Copy(Moto, Stt, 1); if (Moji = '*') or (Moji = '/') then Usen := True; end; if Usen = True then begin Stt := 0; Moji := ''; while (Moji <> '*') and (Moji <> '/') do begin inc(Stt); Moji := Copy(Moto, Stt, 1); end; Kigou := Moji; data := ''; Bgn := Stt-1; Moji := Copy(Moto, Bgn, 1); while (Moji <> '+') and (Moji <> '-') and (Moji <> '*') and (Moji <> '/') and (Bgn > 0) do begin data := Moji + data; dec(Bgn); if Bgn > 0 then Moji := Copy(Moto, Bgn, 1); end; Fext := StrToFloat(data); Frnt := Copy(Moto, 1, Bgn); data := ''; Bgn := Stt+1; Moji := Copy(Moto, Bgn, 1); while (Moji <> '+') and (Moji <> '-') and (Moji <> '*') and (Moji <> '/') and (Bgn <= Length(Moto)) do begin data := data+Moji; inc(Bgn); if Bgn <= Length(Moto) then Moji := Copy(Moto, Bgn, 1); end; Bext := StrToFloat(data); Back := Copy(Moto, Bgn, Length(Moto)-Bgn+1); if Kigou = '*' then data := FloatToStr(Fext*Bext) else if Bext = 0 then data := '0' else data := FloatToStr(Fext/Bext); Moto := Frnt + data + Back; end else begin Fin := True; for Stt := 1 to Length(Moto) do begin Moji := Copy(Moto, Stt, 1); if (Moji = '+') or (Moji = '-') then Fin := False; end; if Fin = False then begin Stt := 0; Moji := ''; while (Moji <> '+') and (Moji <> '-') do begin inc(Stt); Moji := Copy(Moto, Stt, 1); end; Kigou := Moji; data := ''; Bgn := Stt-1; Moji := Copy(Moto, Bgn, 1); while (Moji <> '+') and (Moji <> '-') and (Moji <> '*') and (Moji <> '/') and (Bgn > 0) do begin data := Moji + data; dec(Bgn); if Bgn > 0 then Moji := Copy(Moto, Bgn, 1); end; Fext := StrToFloat(data); Frnt := Copy(Moto, 1, Bgn); data := ''; Bgn := Stt+1; Moji := Copy(Moto, Bgn, 1); while (Moji <> '+') and (Moji <> '-') and (Moji <> '*') and (Moji <> '/') and (Bgn <= Length(Moto)) do begin data := data+Moji; inc(Bgn); if Bgn <= Length(Moto) then Moji := Copy(Moto, Bgn, 1); end; Bext := StrToFloat(data); Back := Copy(Moto, Bgn, Length(Moto)-Bgn+1); if Kigou = '+' then data := FloatToStr(Fext+Bext) else data := FloatToStr(Fext-Bext); Moto := Frnt + data + Back; end; end; end; Result := Moto; end;      J-OH!(VEC05267) Original document by J-OH!     氏 ID:(VEC05267)



ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum