【代码笔记】【c#】中缀表达式转后缀表达式

6 篇文章 0 订阅
		/// <summary>
		/// 中缀表达式转后缀表达式
		/// </summary>
		/// <param name="infix">不需用空格隔开的常规中缀表达式</param>
		/// <returns></returns>
		public static string InToSu(String infix) {

			//将表达式区分数与运算符以空格拆分,得到字符串数组
			String infixFmt = "";
			infix.ToList().ForEach(chr=> {
				if (char.IsDigit(chr) || chr == '.')
					infixFmt += chr;
				else
					infixFmt += " " + chr + " ";
			});
			
			//ps:如果业务规则不允许太多括号嵌套的话 可以通过在这里控制匹配空格量实现
			string[] infixFmts = Regex.Replace(infixFmt, @"\s+", " ").Split(' ');

			Stack<string> op = new Stack<string>(); //存放运算符的栈
			StringBuilder outStr = new StringBuilder(); //最终后缀表达式
			foreach (string unitStr in infixFmts)
			{
				if (isNumberic(unitStr))
				{
					//是数则直接输出
					outStr.AppendWithSpace(unitStr);
				}
				else 
				{
					//是正括号则入栈
					if (unitStr == "(")
					{
						op.Push(unitStr);
					}
					else 
					{
						if (unitStr == ")")
						{
							if (op.Count <= 0)
								throw new ArgumentException("表达式不合法");

							//是反括号则出栈栈中元素并输出直到找到正括号 正括号不输出但要出栈
							string o = "";
							while (o != "(")
							{
								o = op.Pop();
								if (o == "(") break;
								outStr.AppendWithSpace(o);
							}
						}
						else
						{
							//栈中一个运算符没有就入栈
							if (op.Count == 0)
							{
								op.Push(unitStr);
							}
							else
							{
								//有则判断优先级
								if (priorityCompare(unitStr, op.First())) 
								{
									//当前优先级高于栈顶元素优先级 则压入
									op.Push(unitStr);
								}
								else
								{
                                    //当前优先级小于等于栈顶元素优先级 则出栈栈中元素并输出 直到碰到正括号 正括号不出栈 最后压入当前的元素
                                    do
                                    {
                                        if (op.Peek() == "(") break;
                                        outStr.AppendWithSpace(op.Pop());
                                    } while (op.Count > 0 && !priorityCompare(unitStr, op.Peek()));
                                    op.Push(unitStr);
								}
							}
						}
					}	
				}
			}
			//输出剩下的栈中元素
			int c = op.Count;
			for (int i = 0; i < c; i++)
				outStr.AppendWithSpace(op.Pop());

			return outStr.ToString();
		}

AppendWithSpace

    public static class StringBuilderExt
    {
        /// <summary>
        /// 添加元素后加一个空格
        /// </summary>
        /// <param name="stringBuilder"></param>
        /// <param name="str"></param>
        public static StringBuilder AppendWithSpace(this StringBuilder stringBuilder, object str)
        {
            return stringBuilder.AppendFormat("{0} ", str);
        }
    }

priorityCompare

		/// <summary>
		/// 比较优先级 前者大为真 否则为假
		/// </summary>
		/// <param name="op"></param>
		/// <param name="op2"></param>
		/// <returns></returns>
		public static Boolean priorityCompare(string op,string op2)//符号优先级
		{
			if (!"+-*/()".Contains(op) || !"+-*/()".Contains(op2))
				throw new ArgumentException("错误的运算符");

			int p1 = (op == "*" || op == "/")? 2 : (op == "+" || op == "-") ? 1 : 0;
			int p2 = (op2 == "*" || op2 == "/") ? 2 : (op2 == "+" || op2 == "-") ? 1 : 0;

			if (p1 > p2)
				return true;
			else
				return false;
		}

使用:

InToSu("11+4*(3+(3-(9/3-2)))+10/2")

输出:
11 4 3 3 9 3 / 2 - - + * + 10 2 / + 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值