首页 技术 正文
技术 2022年11月11日
0 收藏 368 点赞 3,501 浏览 5471 个字
.代码
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('(') >= )
{
var key1 = Key.Split('(')[];
return "(" + ctx.GetValueByKey(key1);
}
else if (Key.IndexOf(')') >= )
{
var key1 = Key.Split(')')[];
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 - ]))
{
items.Add(word);
}
}
else
{
items.Add(word.Clone().ToString());
items.Add(ch.ToString());
word = string.Empty;
} } int cx = ;
//表达式拆分为字符数组 char[] charArray = exprStr.ToCharArray(); //运算 Expression left = null; Expression right = null; for (int i = ; 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.客户端测试

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

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,092
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,568
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,416
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,189
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,825
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,908