zoukankan      html  css  js  c++  java
  • c# 解释器模式与sping.net表达式的结合应用(金融里经常需要用到公式,这个公式是抽象的需要自己解释)

    1.代码
    using Spring.Expressions;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication49
    {
        public interface IExpressionContext
        {
            /// <summary>
            /// 什么是终结符单词 客户端自己要给出
            /// </summary>
            Dictionary<string, string> map { get; set; }
            string GetValueByKey(string key);
        }
        public class ExpressionContext : IExpressionContext
        {
            public Dictionary<string, string> map { get; set; }
            public string GetValueByKey(string key)
            {
                if (map.ContainsKey(key))
                    return map[key];
                return key;
            }
        }
        public abstract class Expression
        {
            /// <summary>
            /// 终结符
            /// </summary>
            private string key;
            public string Key
            {
                get
                {
                    return key;
                }
    
                set
                {
                    key = value;
                }
            }
    
            //解析公式和数值,其中var中的key值是是公式中的参数,value值是具体的数字
            //这里字典可以抽象为上下文 ctx,此处自己扩展
            public abstract string interpreter(IExpressionContext ctx);
    
        }
    
        public class VarExpression : Expression
        {
    
    
            public VarExpression(string _key)
            {
    
                this.Key = _key;
    
            }
    
    
    
    
            //从map中取之
    
            public override string interpreter(IExpressionContext ctx)
            {
                if (ctx.map.ContainsKey(Key))
                    return ctx.GetValueByKey(Key);
                else if (Key.IndexOf('(') >= 0)
                {
                    var key1 = Key.Split('(')[1];
                    return "(" + ctx.GetValueByKey(key1);
                }
                else if (Key.IndexOf(')') >= 0)
                {
                    var key1 = Key.Split(')')[0];
                    return ctx.GetValueByKey(key1) + ")";
                }
                return Key;
    
            }
    
        }
    
    
        public abstract class SymbolExpression : Expression
        {
    
            protected Expression left;
    
            protected Expression right;
    
            //所有的解析公式都应只关心自己左右两个表达式的结果
    
            public SymbolExpression(Expression _left, Expression _right)
            {
    
                this.left = _left;
    
                this.right = _right;
    
            }
    
    
        }
    
        public class AddExpression : SymbolExpression
        {
    
    
            public AddExpression(Expression _left, Expression _right) : base(_left, _right)
            {
    
    
            }
    
            //把左右两个表达式运算的结果加起来
    
            public override string interpreter(IExpressionContext ctx)
            {
    
                return (base.left.interpreter(ctx)) + "+" + (base.right.interpreter(ctx));
    
            }
    
        }
        public class SubExpression : SymbolExpression
        {
    
    
            public SubExpression(Expression _left, Expression _right) : base(_left, _right)
            {
    
            }
    
            //左右两个表达式相减
    
            public override string interpreter(IExpressionContext ctx)
            {
    
                return base.left.interpreter(ctx) + "-" + base.right.interpreter(ctx);
    
            }
    
        }
        public class MultExpression : SymbolExpression
        {
    
    
            public MultExpression(Expression _left, Expression _right) : base(_left, _right)
            {
    
    
    
            }
    
            //左右两个表达式相减
    
            public override string interpreter(IExpressionContext ctx)
            {
    
                return base.left.interpreter(ctx) + "*" + base.right.interpreter(ctx);
    
            }
    
        }
        public class Dividexpression : SymbolExpression
        {
    
    
            public Dividexpression(Expression _left, Expression _right) : base(_left, _right)
            {
    
    
    
            }
    
            //左右两个表达式相减
    
            public override string interpreter(IExpressionContext ctx)
            {
    
                return base.left.interpreter(ctx) + "/" + base.right.interpreter(ctx);
    
            }
    
        }
        public class PExpression : SymbolExpression
        {
    
    
            public PExpression(Expression _left, Expression _right) : base(_left, _right)
            {
    
    
    
            }
    
            //左右两个表达式相减
    
            public override string interpreter(IExpressionContext ctx)
            {
    
                return base.left.interpreter(ctx) + "^" + base.right.interpreter(ctx);
    
            }
    
        }
    
    
    
        public class Calculator
        {
    
            //定义的表达式
    
            private Expression expression;
    
            //构造函数传参,并解析
    
            public Calculator(string exprStr)
            {
    
                //定义一个堆栈,安排运算的先后顺序
    
                Stack<Expression> stack = new Stack<Expression>();
                string[] sb = { "+", "-", "*", "/", "^" };
                List<string> items = new List<string>();
                string word = string.Empty;
                char[] chs = exprStr.ToCharArray();
                List<string> chsdict = new List<string>();
                foreach (var item in chs)
                {
                    chsdict.Add(item.ToString());
    
                }
                foreach (string ch in chsdict)
                {
    
    
                    if (!sb.Contains(ch.ToString()))
                    {
                        word += ch.ToString();
                        //if (exprStr.IndexOf(ch) == exprStr.ToCharArray().Length - 1)
                        if (object.ReferenceEquals(ch, chsdict[chsdict.Count - 1]))
                        {
                            items.Add(word);
                        }
                    }
                    else
                    {
                        items.Add(word.Clone().ToString());
                        items.Add(ch.ToString());
                        word = string.Empty;
                    }
    
    
                }
    
                int cx = 0;
                //表达式拆分为字符数组
    
                char[] charArray = exprStr.ToCharArray();
    
                //运算
    
                Expression left = null;
    
                Expression right = null;
    
                for (int i = 0; i < items.Count; i++)
                {
                    if (cx >= items.Count)
                    {
                        break;
                    }
                    word = items[cx++];
    
                    switch (word)
                    {
    
                        case "+": //加法
    
                            //加法结果放到堆栈中
    
                            left = stack.Peek();
    
                            right = new VarExpression(items[cx++]);
    
                            stack.Push(new AddExpression(left, right));
    
                            break;
    
                        case "-":
    
                            left = stack.Peek();
    
                            right = new VarExpression(items[cx++]);
    
                            stack.Push(new SubExpression(left, right));
    
                            break;
                        case "^":
    
                            left = stack.Peek();
    
                            right = new VarExpression(items[cx++]);
    
                            stack.Push(new PExpression(left, right));
                            break;
                        case "/":
    
                            left = stack.Peek();
    
                            right = new VarExpression(items[cx++]);
    
                            stack.Push(new Dividexpression(left, right));
                            break;
                        case "*":
                            left = stack.Peek();
    
                            right = new VarExpression(items[cx++]);
    
                            stack.Push(new MultExpression(left, right));
                            break;
                        default: //公式中的变量
                            stack.Push(new VarExpression(word));
                            break;
    
    
                    }
    
                }
    
                //把运算结果抛出来
    
                this.expression = stack.Peek();
    
            }
    
            //开始运算
    
            public string run(IExpressionContext ctx)
            {
    
                return this.expression.interpreter(ctx);
    
            }
    
        }
    
    
        public class Client
        {
    
            //运行四则运算
    
            public static void Main(string[] args)
            {
                while (true)
                {
                    string exp = string.Empty;
                    string expStr = getExpStr();
                    //赋值 得到终结符单词
                    Dictionary<string, string> maps = getValue(expStr);
                    Calculator cal = new Calculator(expStr);
                    IExpressionContext ctx = new ExpressionContext();
                    ctx.map = maps;
                    exp = cal.run(ctx);
                    var val = ExpressionEvaluator.GetValue(null, exp);
                    Console.WriteLine("运算结果为:" + expStr + "=" + exp + "=" + val.ToString());
                }
                Console.ReadKey();
    
            }
    
            //获得表达式
    
            public static String getExpStr()
            {
    
                Console.WriteLine("请输入表达式:");
    
                return Console.ReadLine();
    
            }
    
            //获得值映射 什么才是终结符单词客户端要自己给出定义
    
            public static Dictionary<string, string> getValue(string exprStr)
            {
                exprStr = exprStr.Replace("(", "").Replace(")", "");
    
                //定义非终结符
                string[] sb = { "+", "-", "*", "/", "^" };
    
                string copyExpStr = exprStr.Clone().ToString();
                foreach (char ch in exprStr.ToCharArray())
                {
                    if (sb.Contains(ch.ToString()))
                    {
                        copyExpStr = copyExpStr.Replace(ch.ToString(), ",");
                    }
    
                }
                var items = copyExpStr.Split(',');
    
    
                Dictionary<string, string> map = new Dictionary<string, string>();
    
                //解析有几个参数要传递
    
                foreach (string ch in items)
                {
    
                    if (!sb.Contains(ch.ToString()) && !Regex.IsMatch(ch, @"[0-9]+(.d+)?") && ch != "(" && ch != ")")
                    {
    
                        //解决重复参数的问题
    
                        if (!map.ContainsKey(ch.ToString()))
                        {
                            Console.WriteLine("请输入" + ch + "的值:");
    
                            string in1 = Console.ReadLine();
    
                            map.Add(ch.ToString(), in1);
    
                        }
    
                    }
    
                }
    
                return map;
    
            }
    
        }
    }
    2.客户端测试

  • 相关阅读:
    Java 一边读边写即读一行写一行
    mysql-字符类型
    mysql-数字类型:自增主键踩坑
    mysql-死锁
    mysql-查询的成本
    mysql-独立表空间
    mysql-innodb的表空间
    java-semaphore
    java-CyclicBarrier
    java-countDownLatch
  • 原文地址:https://www.cnblogs.com/kexb/p/6262132.html
Copyright © 2011-2022 走看看