MainPage 〜きまぐれ ぷろぐらま語録〜
 

2024年11月
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24
25
26 27 28 29 30

最近の記事
Blog移転

エアポート2010を見た

花椒油

Steve Jobs,1955-2011

鉄球に無数のとげが付いた武器

M55→M42(T)が欲しい

健康診断done

回転寿司のルール

相模湖リゾート・プレジャー・フ ..

過去ログ 【表示/最小化】
2011年10月
2011年 9月
2011年 8月
2011年 7月
2011年 6月
2011年 5月
2011年 4月
2011年 3月
2011年 2月
2011年 1月
2010年12月
2010年11月
2010年10月
2010年 9月
2010年 8月
2010年 7月
2010年 6月
2010年 5月
2010年 4月
2010年 3月
2010年 2月
2010年 1月
2009年12月
2009年11月
2009年10月
2009年 9月
2009年 8月
2009年 7月
2009年 6月
2009年 5月
2009年 4月
2009年 3月
2009年 2月
2009年 1月
2008年12月
2008年11月
2008年10月
2008年 9月
2008年 6月
2008年 5月
2008年 4月
2008年 3月
2008年 2月
2008年 1月
2007年12月
2007年11月
2007年10月
2007年 9月
2007年 8月
2007年 7月
2007年 6月
2007年 5月
2007年 4月
2007年 3月
2007年 2月
2007年 1月
2006年12月
2006年11月
2006年10月
2006年 9月
2006年 8月
2006年 7月
2006年 6月
2006年 5月

広告欄

 

Blogを移転させました。
新Blogは次のURLです。
https://kerokero.org/wp/




文字列の数式を計算するアルゴリズムの適当な作り方
というわけで、「1+2+3」等の文字列から、
6という数字を求めるアルゴリズムを、
なんちゃってで作る方法。

まずは、計算式というものは、どういう物かを定義します。
こんなこんな感じです。

ほんとは、NBF記法とかの話があるけど直感的に書くとこんな図面。

あとは、この図面に従ってコードをサクッと書くだけ。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Str2Num {
    class Program {
        /// <summary>
        /// メイン関数
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args) {
            string src = "12+34+5*-6+15/2";
            double ret = a(src);
            Console.WriteLine(ret);
        }
        /// <summary>
        /// 関数Aを定義
        /// </summary>
        static double a(string src) {
            int readPos = 0;
            //設計通り、必ず関数Bが最初に呼ばれる。
            double ret = b(src, ref readPos);
            //その後、+か-記号で関数Bの実行を繰り返して行う。
            while (readPos < src.Length && (src[readPos] == '+' || src[readPos] == '-')) {
                if (src[readPos] == '+') {
                    readPos++;
                    ret += b(src, ref readPos);
                } else if (src[readPos] == '-') {
                    readPos++;
                    ret -= b(src, ref readPos);
                } else {
                    throw new Exception();
                }
            }
            return ret;
        }
        /// <summary>
        /// 関数Bを定義
        /// </summary>
        static double b(string src, ref int readPos) {
            //ここも、設計通り、まずは関数Cを呼ぶ。
            double ret = c(src, ref readPos);
            //その後、*か/記号で関数Cの実行を繰り返して行う。
            while (readPos < src.Length && (src[readPos] == '*' || src[readPos] == '/')) {
                if (src[readPos] == '*') {
                    readPos++;
                    ret *= c(src, ref readPos);
                } else if (src[readPos] == '/') {
                    readPos++;
                    ret /= c(src, ref readPos);
                } else {
                    throw new Exception();
                }
            }
            return ret;
        }
        /// <summary>
        /// 関数Cを定義
        /// </summary>
        static double c(string src, ref int readPos) {
            //最後は関数C
            int flag = 1; //単項演算子-のフラグ管理
            double ret = 0;
            //まず、1文字目が-ならば、その旨を覚えておく。
            if (src[readPos] == '-') {
                flag = -1;
                readPos++;
            }
            //符号を除けば、まずは1〜9の数値が来るはず。
            if ('1' <= src[readPos] && src[readPos] <= '9') {
                ret = int.Parse(src[readPos].ToString());
                readPos++;
            } else {
                throw new Exception();//それ以外の文字が来るならばエラー
            }
            //2文字目以降の数字があるかを確認する
            //数値以外が出ていたり、数式を最後まで確認したら終わり。
            while (readPos < src.Length && ('0' <= src[readPos] && src[readPos] <= '9')) {
                //0〜9の数値が見つかったので、戻り値の数値を調整する。
                ret *= 10;
                ret += int.Parse(src[readPos].ToString());
                readPos++;
            }
            return ret * flag;
        }
    }
}

ね?簡単でしょ?

括弧が欲しければ、関数Cの定義を↓こう書き換えればいい。
こんな

以上、BNF表記とか、オートマトンとか、
逆ポーランド記法とかの言葉が分からなくても、
なんちゃってで、文字解析をする方法でした。
01:25, Wednesday, Apr 20, 2011 ¦ 固定リンク ¦ 携帯


■コメント

■コメントを書く

※コメントの受け付けは終了しました

△ページのトップへ
 

最新のつぶやき

サイト内検索
カスタム検索

旅行関係の記事等
九州・広島旅行記 2009(かみちゅ!)
大阪出張(KANON)
大阪出張(ハルヒ)
三宅島旅行記'05
三宅島旅行記'08
三宅島旅行記'10
伊豆半島小旅行

最近のコメント

最近のトラックバック

IPv4枯渇時計

携帯で読む
   URLを携帯に送る





[Valid RSS]

Powered by CGI RESCUE