C#数据结构-前缀中缀后缀+中缀转后缀

目录

一、前缀中缀后缀表达式

1.中缀表达式

2.前缀表达式

3.后缀表达式

二、中缀转后缀


一、前缀中缀后缀表达式

1.中缀表达式

中缀表达式就是平常生活中计算式子的写法,例如:(3+4)*5-6 就是一个中缀表达式

2.前缀表达式

1)前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前

2)要想知道前缀表达式怎么写,需要先了解前缀表达式在计算机中是怎样求值的:从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们进行相应的计算,并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

( 3 + 4 )* 5 - 6 的前缀表达式为 - * + 3 4 5 6

3.后缀表达式

1)后缀表达式又称逆波兰表达式,运算符位于操作数之后

2)后缀表达式在计算机中时怎么求值的:从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们进行相应的计算,并将结果入栈;重复上述过程直到表达式最右端,最后算出的值即为表达式结果。

( 3 + 4 )* 5 - 6 的后缀表达式为 3 4 + 5 * 6 -

二、中缀转后缀

这里直接说过程,不解释原理了,会用就行。

中缀转后缀过程:

1.初始化两个栈:运算符栈s1和储存中间结果栈s2

2.从左至右扫描中缀表达式

3.遇到数字时,直接压入s2

4.遇到运算符时:

1)如果s1为空,或者栈顶为“(”,直接把遇到的运算符压入s1

2)若遇到的运算符比栈顶的运算符优先级高,直接把遇到的运算符压入s1

3)如果栈顶运算符的优先级大于等于遇到运算符的优先级,则把栈顶的运算符弹出并压入s2,然后继续让遇到的运算符和s1中新的栈顶运算符比较,直到遇到的运算符压入s1为止

5.遇到括号时:

1)如果遇到左括号“( ”,直接压入s1

2)如果遇到右括号“ )”,则把s1中最上面的左括号的上面的所有运算符依次弹出并压入s2,然后把这一对括号给清除,也就是把左括号给删了

6.重复步骤2-5,直到表达式最右边

7.将s1中剩余的运算符依次弹出并压入s2

8.此时s2中的顺序为后缀表达式,但依次弹出后为后缀表达式的逆序,所以把s2里面的东西依次弹出后,还需要逆序一下,就是后缀表达式了

但是,在实际写代码过程中,可以灵活运用这个思路,我们其实初始化一个栈就可以了,另外一个栈可以用集合替代,具体看代码:

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace _8.中缀转后缀
{
    class Program
    {
        static void Main(string[] args)
        {
            //测试
            string a = "1+((2+3)*4)-5";
            List<string> b = toInfixExpressionList(a);
            List<string> c = paresSuffixExpreesionList(b);
            foreach (var item in c)
            {
                Console.Write(item);
            }
        }
        //中缀转后缀
        public static List<string> paresSuffixExpreesionList(List<string> ls)
        {
            Stack<string> s1 = new Stack<string>();
            List<string> s2 = new List<string>();
            foreach (var item in ls)
            {
                if(IsInt(item))
                {
                    s2.Add(item);
                }
                else if(item == "(")
                {
                    s1.Push(item);
                }
                else if(item == ")")
                {
                    while(s1.Peek() != "(")
                    {
                        s2.Add(s1.Pop());
                    }
                    s1.Pop();
                }
                else
                {
                    while(s1.Count != 0 && getValue(s1.Peek())>=getValue(item)&&s1.Peek() != "(")
                    {
                        s2.Add(s1.Pop());
                    }
                    s1.Push(item);
                }
            }
            while(s1.Count!=0)
            {
                s2.Add(s1.Pop());
            }
            return s2;
        }
        //返回优先级,数字越大优先级越高
        public static int getValue(string operation)
        {
            switch(operation)
            {
                case "+":
                    return 1;
                case "-":
                    return 1;
                case "*":
                    return 2;
                case "/":
                    return 2;
                default:
                    return 0;
            }
        }
        //判断是否为正整数
        public static bool IsInt(string inString)
        {
            Regex regex = new Regex("^\\d+$");
            return regex.IsMatch(inString.Trim());
        }
        //输入的string放入集合里
        public static List<string> toInfixExpressionList(string s)
        {
            List<string> ls = new List<string>();
            int i = 0;//用于遍历
            string str = "";//对多位数拼接
            char c;//遍历到字符放入c
            while(i<s.Length)
            {
                c = s[i];
                if(c<'0'||c>'9')
                {
                    ls.Add(c.ToString());
                    i++;
                }
                else
                {
                    while(i<s.Length&&s[i]>='0'&&s[i]<='9')
                    {
                        c = s[i];
                        str += c;
                        i++;
                    }
                    ls.Add(str);
                    str = "";
                }
            }
            return ls;
        }
    }
}

把string变成list(集合)容易操作。

为什么用一个栈就行:理解的时候用两个栈更好理解,实际写代码过程中,只需要初始化一个栈(s1)和一个集合(s2),那为什么另一个栈(s2)变成集合更好,因为变成集合后,就可以不用逆序就是最后的后缀表达式(可以直接用),如果s2用栈的话,最后弹出后,还需要再逆序一下才为后缀表达式。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值