语文不好,不太会组织语言,希望不要太在意。

如题,先简要介绍一下什么是逆波兰式  通常我们在写数学公式的时候  就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀表达式就为ab+

而把中缀表达式转为逆波兰式也是很容易的,以下算法摘自百度百科

简要说一下栈,栈是一种先进后出的对象集合,可以把栈理解为一个桶,先进后出  Stack   Peek()是取出但是不剔除 做比较的时候用,Pop()是出栈,Push()入栈

首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆波兰式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:
(1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈
(2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,最后将该运算符送入S1栈。
(3)若取出的字符是“(”,则直接送入S1栈顶。
(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。
(5)重复上面的1~4步,直至处理完所有的输入字符
(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。
完成以上步骤,S2栈便为逆波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆波兰式的计算方法计算了!把一个表达式转为逆波兰式  比如 (a+b)*c 逆波兰式为ab+c*
a为数字,入栈,b为数字,入栈,“+”,为运算符  a b出栈,计算a+b 然后将结果 入栈,c入栈,"*"为运算符,a+b的结果出栈,c出栈,运算 * 将结果再入栈 运算完毕,栈里的结果就是我们想要的了
 
代码实现(有点乱)
 
判断元素是不是为数字
     static bool IsNumber(string s)
{
return Regex.IsMatch(s, @"\d+");
}

判断元素是否为运算符(+-*/)

     static bool IsSiZe(string s)
{
string ts = "+-*/";
return ts.IndexOf(s) > -;
}

判断优先级

  static int Level(string s)
{
int i = ;
switch (s)
{
case ",":
i = ;
break;
case "(":
case ")":
case "#":
i = ;
break;
case "+":
case "-":
i = ;
break;
case "*":
case "/":
i = ;
break;
}
return i;
}

计算

   private static void Calc(Stack<string> numStack, Stack<string> operStack)
{
int rightnum = int.Parse(numStack.Pop());
int leftnum = int.Parse(numStack.Pop());
string oper = operStack.Pop();
switch (oper)
{
case "+":
numStack.Push((leftnum + rightnum).ToString());
break;
case "-":
numStack.Push((leftnum - rightnum).ToString());
break;
case "*":
numStack.Push((leftnum * rightnum).ToString());
break;
case "/":
numStack.Push((leftnum / rightnum).ToString());
break;
} }

总体实现代码

   static void ToNiBoLan(string exp)
{
operStack.Push("#"); //进栈 便于比较 string token = "";
for (int i = 0; i < exp.Length; i++)
{
if (IsNumber(exp[i].ToString())) //如果是数字
{
token += exp[i].ToString();
}
else if (exp[i].ToString() == "(") //左括号直接进栈
{
operStack.Push(exp[i].ToString());
if (IsNumber(token))
numStack.Push(token);
token = "";
}
else if (IsSiZe(exp[i].ToString()))
{
if (IsNumber(token))
numStack.Push(token);
token = "";
int item = Level(exp[i].ToString()).CompareTo(Level(operStack.Peek())); //比较运算符优先级
if (item > 0) //如果优先级高于栈顶,运算符进栈
{
operStack.Push(exp[i].ToString());
}
else //如果运算符小于或等于栈顶 进行计算 并将运算符进栈
{ Calc(numStack, operStack); operStack.Push(exp[i].ToString());
} }
else if (exp[i].ToString() == ")") //如果遇到右括号 依次遍历进行计算直至遇到左括号
{
if (IsNumber(token))
numStack.Push(token);
token = "";
while (operStack.Peek() != "(")
{
Calc(numStack, operStack);
}
token = numStack.Pop(); //拿出数字便于进行下一次计算
operStack.Pop(); //符合条件的左括号出栈 }
else //遍历结束
{
if (IsNumber(token))
numStack.Push(token);
token = "";
while (numStack.Count > 1)
{
Calc(numStack, operStack);
}
}
}
}

  调用

   string s = Console.ReadLine()+"#";  //为了便于比较,在表达式结尾加上"#"
ToNiBoLan(s);
Console.WriteLine(numStack.Pop());

  总体代码如此

 

c# 逆波兰式实现计算器的更多相关文章

  1. HDU1237 简单的计算器 【堆】+【逆波兰式】

    简单的计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. HDU1237 简单计算器 【栈】+【逆波兰式】

    简单计算器 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  3. javascript:逆波兰式表示法计算表达式结果

    逆波兰式表示法,是由栈做基础的表达式,举个例子: 5 1 2 + 4 * + 3 -  等价于   5 + ((1 + 2) * 4) - 3 原理:依次将5 1 2 压入栈中, 这时遇到了运算符 + ...

  4. Haskell解决逆波兰式

    摘自<Haskell趣学指南- Learn You a Haskell for Great Good> {- 逆波兰式(revese polish notation, RPN): 操作符出 ...

  5. [LeetCode]Evaluate Reverse Polish Notation(逆波兰式的计算)

    原题链接:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ 题目描述: Evaluate the value of a ...

  6. python 逆波兰式

    逆波兰式,也叫后缀表达式 技巧:为简化代码,引入一个不存在的运算符#,优先级最低.置于堆栈底部 class Stack(object): '''堆栈''' def __init__(self): se ...

  7. codechef Transform the Expression 转换成逆波兰式

    版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/.未经本作者同意不得转载. https://blog.csdn.net/kenden23/article ...

  8. NYOJ 35 表达式求值(逆波兰式求值)

    http://acm.nyist.net/JudgeOnline/problemset.php?typeid=4 NYOJ 35 表达式求值(逆波兰式求值) 逆波兰式式也称后缀表达式. 一般的表达式求 ...

  9. Evaluate Reverse Polish Notation(逆波兰式)

    Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...

随机推荐

  1. 日常:css样式、选择器、个别知识点、数组array

    优先加入css引入文件定义,个别的在下面用style改变.(从左往右,从上往下)CSS样式表1.内联样式表(优先级最高)(改个别的)<div style="width:100px; h ...

  2. Redis 安装与初体验

    一.Redis简介 Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(s ...

  3. 使用PHP生成二维码(PHPQRCode)

    关于什么是二维码,可以阅读 http://baike.baidu.com/view/132241.htm 这里就不多讲了,二维码的应用非常广泛,似乎一夜之间渗透到我们生活的方方面面,地铁广告.报纸.火 ...

  4. Keepalived + HAProxy 搭建【第二篇】Keepalived 安装与配置

    第一步:准备 1. 简介 本文搭建的是利用 Keepalived 实现 HAProxy 的热备方案,即两台主机上的 HAProxy 实例同时运行,其中全总较高的实例为 MASTER,MASTER出现异 ...

  5. C语言中NULL的定义

    用C语言编程不能不说指针,说道指针又不能不提NULL,那么NULL究竟是个什么东西呢? C语言中又定义,定义如下: #undef NULL #if defined(__cplusplus) #defi ...

  6. json基础入门

    json是什么? JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成.它基于ECMAScript的一个子集. JSO ...

  7. Linux基础命令操作实例

    1.开启Linux操作系统,要求以root用户登录GNOME图形界面,语言支持选择为汉语 2.使用快捷键切换到虚拟终端2,使用普通用户身份登录,查看系统提示符 使用快捷键Ctrl+Alt+F2切换到终 ...

  8. react router路径的匹配原则

    路由匹配规则是从上到下执行,一旦发现匹配,就不再其余的规则了. (1):paramName :paramName匹配URL的一个部分,直到遇到下一个/.?.#为止.这个路径参数可以通过this.pro ...

  9. Bootsrap 的 Carousel

    一.简介 Carousel 就是指轮播图,这里 有完整的代码例子.它可以很简单的就构造出来,结构如下: div.carousel.slide[data-ride="carousel" ...

  10. ASP.NET Core MVC之ViewComponents(视图组件)

    前言 大概一个来星期未更新博客了,久违了各位,关于SQL Server性能优化会和ASP.NET Core MVC穿插来讲,如果你希望我分享哪些内容可以在评论下方提出来,我会筛选并看看技术文档来对你的 ...