zoukankan      html  css  js  c++  java
  • 计算器修正代码

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        public class CharExt
        {
            public int index;
            public char value;
        }
        public class LinkChar
        {
            public string expstr;
            /// <summary>
            /// 索引链表元素
            /// </summary>
            /// <param name="index"></param>
            /// <returns></returns>
            public LinkChar find(int index)
            {
                LinkChar tmp = this.header;
                while (tmp != null)
                {
                    if (tmp.ch.index == index)
                    {
                        return tmp;
                    }
                    tmp = tmp.next;
                }
                return null;
            }
            //获取链表两个节点之间的内容
            public static string GetContent(LinkChar start, LinkChar end)
            {
                string content = string.Empty;
                LinkChar tmp = start;
                while (tmp != end)
                {
                    content += tmp.ch.value.ToString();
                    tmp = tmp.next;
                }
                content += end.ch.value;
                return content;
    
            }
            public void show()
            {
                LinkChar tmp = this.header;
                while (tmp != null)
                {
                    Debug.WriteLine(tmp.ch.index + ":" + tmp.ch.value);
                    tmp = tmp.next;
                }
            }
            /// <summary>
            /// 将链表内容还原成字符串
            /// </summary>
            /// <returns></returns>
            /// <summary>
            /// 将链表内容还原成字符串
            /// </summary>
            /// <returns></returns>
            public string GetExpStr()
            {
                string str = string.Empty;
                LinkChar tmp = this.header;
                while (tmp != null)
                {
                    str += tmp.ch.value;
                    tmp = tmp.next;
                }
                return str;
            }
            public LinkChar GetPatialLink(int start, int end)
            {
                return null;
            }
            public LinkChar()
            {
    
            }
            public void Push(string expstr)
            {
                var cs = expstr.ToCharArray();
                for (int i = 0; i < cs.Length; i++)
                {
                    char item = cs[i];
                    if (i == 0)
                    {
    
                        this.current = new LinkChar() { ch = new CharExt() { value = cs[i], index = i } };
                        this.header = this.current;
                    }
                    else
                    {
                        var tmpNext = new LinkChar() { ch = new CharExt() { value = cs[i], index = i } };
                        if (i == cs.Length - 1)
                        {
                            laster = tmpNext;
                        }
                        this.current.next = tmpNext;
                        this.current.next.prior = this.current;
                        this.current = this.current.next;
                    }
    
    
                }
            }
            public LinkChar laster;
            public LinkChar header;
            public CharExt ch;
            public LinkChar current;
            public LinkChar prior;
            public LinkChar next;
    
        }
        public class kuohaodui
        {
            //左括号
            public int index1;
            //右括号
            public int index2;
        }
        //括号栈
        public class KuoHaoStack
        {
            //用于匹配括号对
            public Stack<kuohaodui> dui { get; set; }
    
            public static bool jiaoyan(string expstr)
            {
                int count1 = 0;
                int count2 = 0;
                char[] chs = expstr.ToCharArray();
                for (int i = 0; i < chs.Length; i++)
                {
                    char ch = chs[i];
                    if (ch == '(')
                    {
                        count1++;
    
                    }
                    else if (ch == ')')
                    {
                        count2++;
                    }
    
                }
                bool p = count1 == count2;
                return p;
            }
        }
        public class DbContext
        {
            public Dictionary<string, double> dic = new Dictionary<string, double>();
    
            internal double getValue(string key)
            {
                return dic[key];
            }
            public Dictionary<string, double> Map(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(',');
    
                //解析有几个参数要传递
    
                foreach (string ch in items)
                {
    
                    if (!sb.Contains(ch.ToString()) && !Regex.IsMatch(ch, @"[0-9]+(.d+)?") && ch != "(" && ch != ")")
                    {
    
                        //解决重复参数的问题
    
                        if (!dic.ContainsKey(ch.ToString()))
                        {
                            Console.WriteLine("请输入" + ch + "的值:");
    
                            string in1 = Console.ReadLine();
    
                            dic.Add(ch.ToString(), double.Parse(in1));
    
                        }
    
                    }
    
                }
    
                return dic;
    
            }
    
    
        }
        public abstract class Expression
        {
            public abstract double jieshi(DbContext context);
    
    
        }
        public class AddExpression : Expression
        {
            public Expression Left;
            public Expression Right;
            public AddExpression(Expression left, Expression right)
            {
                this.Left = left;
                this.Right = right;
            }
    
            public override double jieshi(DbContext context)
            {
                return Left.jieshi(context) + Right.jieshi(context);
            }
        }
        public class SubExpression : Expression
        {
            public Expression Left;
            public Expression Right;
            public SubExpression(Expression left, Expression right)
            {
                this.Left = left;
                this.Right = right;
            }
    
            public override double jieshi(DbContext context)
            {
                return Left.jieshi(context) - Right.jieshi(context);
            }
    
        }
    
        public class MultExpression : Expression
        {
            public Expression Left;
            public Expression Right;
            public MultExpression(Expression left, Expression right)
            {
                this.Left = left;
                this.Right = right;
            }
    
            public override double jieshi(DbContext context)
            {
                return Left.jieshi(context) * Right.jieshi(context);
            }
    
        }
        public class DivedeExpression : Expression
        {
            public Expression Left;
            public Expression Right;
            public DivedeExpression(Expression left, Expression right)
            {
                this.Left = left;
                this.Right = right;
            }
            public override double jieshi(DbContext context)
            {
                return Left.jieshi(context) / Right.jieshi(context);
            }
    
        }
        public static class StringEXT
        {
            public static bool IsNum(this string str)
            {
                return Regex.IsMatch(str, @"(d+)(.(d+))?");
            }
        }
        public class VarExpression : Expression
        {
            private string key;
            public VarExpression(string key)
            {
                this.key = key;
            }
            public override double jieshi(DbContext context)
            {
                return context.getValue(this.key);
            }
        }
        public class Calculator
        {
            /// <summary>
            /// 定义优先级 索引出来的值越小 优先级越高
            /// </summary>
            /// <returns></returns>
            public Dictionary<string, int> youxianji()
            {
                Dictionary<string, int> youxian = new Dictionary<string, int>();
                youxian.Add("(", 3);
                youxian.Add("*", 2);
                youxian.Add("/", 2);
                youxian.Add("+", 1);
                youxian.Add("-", 1);
                return youxian;
            }
            /// <summary>
            /// 终结符字典
            /// </summary>
            /// <returns></returns>
            public Dictionary<string, double> dic()
            {
                DbContext context = new DbContext();
                context.Map(linkList.GetExpStr());
                return context.dic;
            }
    
            public string findNextElement(LinkChar firtFuHao, LinkChar chs)
            {
                //a+(b+c)*(c/d)
                //a+b*(c+d)
                //a+(b*c*d)+e
                //(((a+b+c))*d+(e+f+g))*h
    
                LinkChar nextFuHao = null;
                //循环开始元素
                LinkChar linkElementStart = firtFuHao;
                while (true)
                {
                    if (linkElementStart.next.ch.value == '(')
                    {
                        int index2 = KuohaoduiStack.FirstOrDefault(x => x.index1 == linkElementStart.next.ch.index).index2;
                        nextFuHao = chs.find(index2 + 1);
                        if (nextFuHao == null)
                        {
                            string content = LinkChar.GetContent(firtFuHao.next, chs.find(index2));
                            return content;
                        }
                        char c = nextFuHao.ch.value;
                        if (c != '+' && c != '-' && c != '*' && c != '/')
                        {
                            string content = LinkChar.GetContent(firtFuHao.next, nextFuHao.prior);
                            return content;
                        }
                    }
                    else
                    {
                        if (linkElementStart.next == chs.laster)
                        {
                            nextFuHao = linkElementStart.next;
                        }
                        else
                        {
                            nextFuHao = linkElementStart.next.next;
                        }
                    }
                    //优先级
                    Dictionary<string, int> yxj = youxianji();
                    if (nextFuHao == null)
                    {
                        string s = string.Empty;
                        LinkChar ch = firtFuHao.next;
                        while (ch != null)
                        {
                            s += ch.ch.value.ToString();
                            ch = ch.next;
                        }
                        return s;
                    }
                    string key2 = nextFuHao?.ch.value.ToString();
                    string key1 = linkElementStart.ch.value.ToString();
                    int you2 = key2 != null && !yxj.ContainsKey(key2) ? 1 : yxj[key2 == null ? "+" : key2];
                    int you1 = yxj[key1];
                    if (you2 <= you1)
                    {
                        break;
                    }
                    linkElementStart = nextFuHao;
                }
                var tmp = firtFuHao;
                string str = string.Empty;
                int count = 0;
                while (true)
                {
                    int maxSize = youxianji().ContainsKey(nextFuHao.ch.value.ToString())
                        ? nextFuHao.ch.index - firtFuHao.ch.index - 1
                        : nextFuHao.ch.index - firtFuHao.ch.index;
                    if (count < maxSize)
                    {
                        tmp = tmp.next;
                        count++;
                        str += tmp.ch.value.ToString();
    
                    }
                    else
                    {
                        count = 0;
                        break;
                    }
                }
                return str;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="chs">输入的表达式链表</param>
            /// <param name="startIndex">符号(+-*/)之后的第一个字符</param>
            /// <returns></returns>
            public string GetRightKey(LinkChar chs, int startIndex)
            {
                //a+b*(c+d)
                //a+(b*c*d)+e
                LinkChar fuhao = chs.find(startIndex - 1);
                //找到下个元素的符号
                return findNextElement(fuhao, chs);
            }
            /// <summary>
            /// 是否是未匹配的右括号
            /// </summary>
            /// <param name="t1"></param>
            /// <param name="startP"></param>
            /// <returns></returns>
            public bool weiPiPeiYouKuoHao(LinkChar youP)
            {
                return _KuohaoduiStack.Count(x => x.index2 == youP.ch.index) <= 0;
            }
            public bool weiPiPeiZuoKuoHao(LinkChar zuoP)
            {
                return _KuohaoduiStack.Count(x => x.index1 == zuoP.ch.index) <= 0;
            }
            public LinkChar linkList;
            private Stack<kuohaodui> _KuohaoduiStack = new Stack<kuohaodui>();
            public Stack<kuohaodui> KuohaoduiStack
            {
                get
                {
                    //1.括号匹配
                    //()+() 
                    //(()+())
                    //(())
                    LinkChar tmp = linkList.header;
                    while (tmp != null)
                    {
                        //当匹配左括号的时候,找到匹配的右括号,压入括号栈内
                        if (tmp.ch.value == '(')
                        {
                            //(a+b)+(a*(c+d))/e
    
                            //开始匹配的链表元素(右括号)
                            var startP = tmp.next;
    
    
                            while (startP != null)
                            {
                                if (startP.ch.value == ')' && weiPiPeiYouKuoHao(startP))
                                {
                                    var t1 = startP.prior;
    
                                    while (true)
                                    {
                                        //找到左括号
                                        if (t1.ch.value != '(')
                                        {
                                            t1 = t1.prior;
                                            continue;
                                        }
                                        else
                                        {
                                            //不仅要是左括号,还必须是未匹配的左括号
                                            if (!weiPiPeiZuoKuoHao(t1))
                                            {
                                                t1 = t1.prior;
                                                continue;
                                            }
                                            if (_KuohaoduiStack.Count(x => x.index1 == t1.ch.index && x.index2 == startP.ch.index) <= 0)
                                            {
                                                _KuohaoduiStack.Push(new kuohaodui { index1 = t1.ch.index, index2 = startP.ch.index });
                                                break;
                                            }
    
    
                                        }
                                    }
    
                                }
    
                                startP = startP.next;
                            }
    
    
                        }
    
                        tmp = tmp.next;
                    }
                    return _KuohaoduiStack;
                }
            }
    
            public Dictionary<string, double> zhongjiefuDic { get; set; }
            public Expression cal(LinkChar chs)
            {
                Expression left = null;
                Expression right = null;
                //linkList = chs;
                string rightkey = string.Empty;
                Stack<Expression> stack = new Stack<Expression>();
                LinkChar tmp = chs.header;
                var jieshu = 0;
                Dictionary<string, double> maps = zhongjiefuDic;
                while (tmp != null)
                {
                    if (tmp == chs.laster || tmp == null)
                    {
                        jieshu = 1;
                    }
                    char c = tmp.ch.value;
                    switch (c)
                    {
                        case '+':
                            left = stack.Pop();
                            rightkey = GetRightKey(chs, tmp.ch.index + 1);
                            if (maps.ContainsKey(rightkey))
                            {
                                right = new VarExpression(rightkey);
                            }
                            else
                            {
                                var tmp11 = new LinkChar();
                                tmp11.header = tmp.next;
                                tmp11.laster = tmp11.header;
                                for (int i = 0; i < rightkey.Length - 1; i++)
                                {
                                    tmp11.laster = tmp11.laster.next;
                                }
                                right = cal(tmp11);
                            }
                            if (tmp.ch.index + 1 == chs.laster.ch.index)
                            {
                                jieshu = 1;
                            }
                            for (int i = 0; i < rightkey.Length; i++)
                            {
                                tmp = tmp.next;
                            }
                            stack.Push(new AddExpression(left, right));
                            if (tmp == chs.laster || tmp == null)
                            {
                                return stack.Pop();
                            }
                            break;
                        case '-':
                            left = stack.Pop();
                            rightkey = GetRightKey(chs, tmp.ch.index + 1);
                            if (maps.ContainsKey(rightkey))
                            {
                                right = new VarExpression(rightkey);
                            }
                            else
                            {
                                var tmp11 = new LinkChar();
                                tmp11.header = tmp.next;
                                tmp11.laster = tmp11.header;
                                for (int i = 0; i < rightkey.Length - 1; i++)
                                {
                                    tmp11.laster = tmp11.laster.next;
                                }
                                right = cal(tmp11);
                            }
                            if (tmp.ch.index + 1 == chs.laster.ch.index)
                            {
                                jieshu = 1;
                            }
                            for (int i = 0; i < rightkey.Length; i++)
                            {
                                tmp = tmp.next;
                            }
                            stack.Push(new SubExpression(left, right));
                            if (tmp == chs.laster || tmp == null)
                            {
                                return stack.Pop();
                            }
                            break;
                        case '*':
                            left = stack.Pop();
                            rightkey = GetRightKey(chs, tmp.ch.index + 1);
                            if (maps.ContainsKey(rightkey))
                            {
                                right = new VarExpression(rightkey);
                            }
                            else
                            {
                                var tmp11 = new LinkChar();
                                tmp11.header = tmp.next;
                                tmp11.laster = tmp11.header;
                                for (int i = 0; i < rightkey.Length - 1; i++)
                                {
                                    tmp11.laster = tmp11.laster.next;
                                }
                                right = cal(tmp11);
                            }
                            if (tmp.ch.index + 1 == chs.laster.ch.index)
                            {
                                jieshu = 1;
                            }
                            for (int i = 0; i < rightkey.Length; i++)
                            {
                                tmp = tmp.next;
                            }
                            stack.Push(new MultExpression(left, right));
                            if (tmp == chs.laster || tmp == null)
                            {
                                return stack.Pop();
                            }
                            break;
                        case '/':
                            left = stack.Pop();
                            rightkey = GetRightKey(chs, tmp.ch.index + 1);
                            if (maps.ContainsKey(rightkey))
                            {
                                right = new VarExpression(rightkey);
                            }
                            else
                            {
                                var tmp11 = new LinkChar();
                                tmp11.header = tmp.next;
                                tmp11.laster = tmp11.header;
                                for (int i = 0; i < rightkey.Length - 1; i++)
                                {
                                    tmp11.laster = tmp11.laster.next;
                                }
                                right = cal(tmp11);
                            }
                            if (tmp.ch.index + 1 == chs.laster.ch.index)
                            {
                                jieshu = 1;
                            }
                            for (int i = 0; i < rightkey.Length; i++)
                            {
                                tmp = tmp.next;
                            }
                            stack.Push(new DivedeExpression(left, right));
                            if (tmp == chs.laster || tmp == null)
                            {
                                return stack.Pop();
                            }
                            break;
                        case '(':
                            int lIndex = tmp.ch.index;
                            int start = tmp.ch.index + 1;
                            int end = KuohaoduiStack.FirstOrDefault(x => x.index1 == lIndex).index2 - 1;
                            var tmp1 = new LinkChar();
                            tmp1.header = chs.find(start);
                            tmp1.laster = chs.find(end);
                            for (int i = 0; i < (end - start + 1) + 1; i++)
                            {
                                tmp = tmp.next;
                            }
                            //tmp = tmp1.laster;
                            stack.Push(cal(tmp1));
                            if (tmp == chs.laster || tmp == null)
                            {
                                return stack.Pop();
                            }
                            break;
                        default:
                            Expression varExpression = new VarExpression(c.ToString());
                            stack.Push(varExpression);
                            break;
                    }
                    tmp = tmp.next;
                    if (tmp != null && tmp.ch.value == ')')
                    {
                        tmp = tmp.next;
                    }
                    if (jieshu == 1 || tmp == null)
                    {
                        break;
    
                    }
                }
                return stack.Pop();
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
    
                while (true)
                {
                    string str = Console.ReadLine(); //"a+(b*c+d)+e";
                    char[] chs1 = str.ToCharArray();
                    //1.括号校验 start
                    bool p = KuoHaoStack.jiaoyan(str);
                    if (p == false)
                    {
                        Console.WriteLine("请重新输入!!");
                        break;
                    }
                    //1. 括号校验end
    
    
                    //2. 字符放到LinkChar里 strat
                    List<CharExt> chs = new List<CharExt>();
                    LinkChar linklist = new LinkChar();
                    linklist.Push(str.Replace(" ", ""));
                    //字符放到LinkChar里 end
    
    
                    //3. 产生上下文
                    DbContext context = new DbContext();
                    context.Map(str);
    
                    //4.设计计算器产生表达式
                    Calculator calulator = new Calculator();
                    calulator.zhongjiefuDic = context.dic;
                    calulator.linkList = linklist;
                    Expression expression = calulator.cal(linklist);
    
                    //5.进行表达式的解释出结果
                    double result = expression.jieshi(context);
    
                    //6.输出结果
                    Console.WriteLine(str + "=" + result);
    
    
                }
                Console.ReadKey();
            }
        }
    }
  • 相关阅读:
    git(1)-git关联GitHub-windows-转载
    jenkins(4)-jenkins配置邮件通知
    jenkins(3)-linux下安装jenkins(yum install方式)
    【PAT甲级】1090 Highest Price in Supply Chain (25 分)(DFS)
    【PAT甲级】1087 All Roads Lead to Rome (30 分)(MAP【int,string】,邻接表,DFS,模拟,SPFA)
    【PAT甲级】1018 Public Bike Management (30 分)(DFS,SPFA)
    Educational Codeforces Round 61 (Rated for Div. 2) G(线段树,单调栈)
    Atcoder Grand Contest 032C(欧拉回路,DFS判环)
    Educational Codeforces Round 62 (Rated for Div. 2)E(染色DP,构造,思维,组合数学)
    Atcoder Grand Contest 031C(构造,思维,异或,DFS)
  • 原文地址:https://www.cnblogs.com/kexb/p/6297714.html
Copyright © 2011-2022 走看看