后缀表达式计算

来源:互联网 发布:绘声绘影软件 编辑:程序博客网 时间:2024/05/19 13:57

http://www.cppblog.com/deep2/archive/2008/10/25/65021.aspx

 

// test20.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include
<iostream>
#include
<stack>
#include
<string>
using namespace std;

class PostExp{
public:
    PostExp(
string str):evalStr(str){}
    
int evaluate();
private:
    
string evalStr;
    stack
<int> postStack;
};

/**
算式中的数字限定在0~9,因为是通过string分别读取每一个元素,如89被认定为8和9
如果操作数要扩大到9以上,则应该用数组保存算式中的每一个元素
此处为方便起见,只是为了表达后缀表达式的基本算法
*/
int PostExp::evaluate(){//后缀表达式计算
    for(string::iterator iter=evalStr.begin(); iter!=evalStr.end(); iter++){//从前至后读取
        int x,y,z;
        
if(*iter>='0' && *iter<='9')
            postStack.push(
*iter - '0');//如果读到数字,压栈
        else{//如果读到操作符,出栈两个操作数,并计算
            y=postStack.top();//y保存操作符右边的数字
            postStack.pop();
            x
=postStack.top();//x保存操作符左边的数字
            postStack.pop();
            
switch(*iter){
                    
case '+': z=x+y; break;//z保存计算结果
                    case '-' : z=x- y; break;
                    
case '*': z=x*y; break;
                    
case '/' : z=x/y;  break;
            }
            postStack.push(z);
//把计算结果作为操作数压栈
        }
    }
    
return postStack.top();
}

int main(){
    PostExp
* pe=new PostExp("352*5+-");
    cout
<<pe->evaluate();
    system(
"pause");
}

 

=================

http://blog.csdn.net/xiazdong/article/details/7272693

一、后缀表达式介绍


后缀表达式的特点就是计算机运算非常方便,需要用到栈;计算机处理过程只需要顺序读入,如果遇到数字,则放入栈中,如果是运算符,则将两个栈中数字取出进行运算;

比如1+2的后缀表达式为12+;

而栈可以把一般的中缀表达式变成后缀表达式,并且计算后缀表达式得出结果,因此此应用在计算器中非常常用;


二、中缀表达式转换成后缀表达式


此方法需要遵循几个规则:

(1)如果读入操作数,则直接放入输出字符串;

(2)如果读入一般运算符如+-*/,则放入堆栈,但是放入堆栈之前必须要检查栈顶,并确定栈顶运算符的优先级比放入的运算符的优先级低;如果放入的优先级较低,则需要将栈顶的运算符放入输出字符串;

(3)如果读入(,因为左括号优先级最高,因此放入栈中,但是注意,当左括号放入栈中后,则优先级最低;

(4)如果读入),则将栈中运算符取出放入输出字符串,直到取出(为止,注意:()不输出到输出字符串;

(5)顺序读完表达式,如果栈中还有操作符,则弹出,并放入输出字符串;

  

三、计算后缀表达式



规则如下:

(1)如果是操作数,则放入栈中;

(2)如果是操作符,则取出栈中两个操作数,进行运算后,将结果放入栈中;

(3)直到最后栈中只有一个元素,此元素就是计算结果;

 

四、代码


以下代码是计算器的辅助代码,通过此代码可以快速进行计算。

输入: 四则运算(支持括号)

输出:结果字符串


[java] view plaincopyprint?
  1. package org.xiazdong.Calculatorutils;  
  2.   
  3. import java.util.Stack;  
  4.   
  5.   
  6.   
  7. /** 
  8.  * 计算器工具类 
  9.  * 完成整数、浮点的加、减、乘、除、括号运算 
  10.  *  
  11.  * 禁忌:如果出现.5表示0.5,则结果不正确 
  12.  * @author xiazdong 
  13.  * 
  14.  */  
  15. public class CalculatorUtils {  
  16.     /** 
  17.      * 将中缀表达式转换成后缀表达式 规则: 1.如果是操作数,则添加到输出流 2.如果是(,则添加栈中; 
  18.      * 3.如果是),则将栈中操作符移入输出流,直到(为止,()不添加入输出流 4.如果是一般操作符(+-* 
  19.      * /),则加入栈之前,需要检查栈中的操作符的优先级,如果栈顶优先级比添加的优先级高,则将栈顶操作符移入输出流,否则直接添加操作符; 
  20.      */  
  21.       
  22.     public static String calculate(String str){  
  23.         return calculateReversePolish(exchangeToReversePolish(str));  
  24.     }  
  25.       
  26.     private static String exchangeToReversePolish(String str) {  
  27.         // 1.创建Stack   
  28.         Stack<String> s = new Stack<String>();  
  29.         // 2.创建输出流字符串   
  30.         StringBuilder builder = new StringBuilder();  
  31.         // 3.解析中缀表达式   
  32.         // 3.1 如果是读到数字,则接着读,直到读到操作符为止   
  33.         for (int i = 0, numLenCount = 1; i < str.length(); i += numLenCount) {  
  34.             char ch = str.charAt(i);  
  35.             String operand = ch + "";  
  36.             numLenCount = 1;  
  37.             if ((ch + "").matches("\\d{1}")) {  
  38.                 numLenCount = 1;  
  39.                 char nextChar = 0;  
  40.                 if ((i + numLenCount) < str.length()) { // 下一个字符是否超过边界长度  
  41.                     nextChar = str.charAt(i + numLenCount);  
  42.                     while ((nextChar + "").matches("[.\\d{1}]")) {  
  43.                         operand += nextChar;  
  44.                         if ((i + numLenCount + 1) < str.length()) {  
  45.                             nextChar = str.charAt(i + numLenCount + 1);  
  46.                             numLenCount++;  
  47.                         } else {  
  48.                             numLenCount++;  
  49.                             break;  
  50.                         }  
  51.                     }  
  52.                 }  
  53.                 operand += " ";  
  54.                 builder.append(operand);  
  55.   
  56.             } else {  
  57.                 if (ch == '(') {  
  58.                     s.push(ch + "");  
  59.                 } else if (ch == '+' || ch == '-') {  
  60.                     while (s.size() > 0 && s.peek().matches("[-+*/]")) {  
  61.                         builder.append(s.pop() + " ");  
  62.                     }  
  63.                     s.push(ch + "");  
  64.                 } else if (ch == '*' || ch == '/') {  
  65.                     while (s.size() > 0 && s.peek().matches("[*/]")) {  
  66.                         builder.append(s.pop() + " ");  
  67.                     }  
  68.                     s.push(ch + "");  
  69.                 } else if (ch == ')') {  
  70.                     while (s.size() > 0 && !s.peek().equals("(")) {  
  71.                         builder.append(s.pop() + " ");  
  72.                     }  
  73.                     s.pop();  
  74.                 }  
  75.             }  
  76.         }  
  77.         while (s.size() > 0) {  
  78.             builder.append(s.pop() + " ");  
  79.         }  
  80.         System.out.println(builder);  
  81.         return builder.toString();  
  82.   
  83.     }  
  84.   
  85.     /** 
  86.      * 计算后缀表达式 
  87.      *  
  88.      */  
  89.     private static String calculateReversePolish(String str) {  
  90.   
  91.         String[] splitStr = str.split(" ");  
  92.         Stack<String> s = new Stack<String>();  
  93.         for (int i = 0; i < splitStr.length; i++) {  
  94.             String ch = splitStr[i];  
  95.             if (ch.matches("\\d+.\\d+")||ch.matches("\\d+")) {  
  96.                 s.push(ch);  
  97.             } else {  
  98.                 if (s.size() >= 2) {  
  99.                     String c1 = s.pop();  
  100.                     String c2 = s.pop();  
  101.                     if (ch.equals("+")) {  
  102.                         if(c1.contains(".")||c2.contains(".")){  
  103.                             s.push(String.valueOf((Double.parseDouble(c2 + "") + Double  
  104.                                 .parseDouble(c1 + ""))));  
  105.                         }  
  106.                         else{  
  107.                             s.push(String.valueOf((Integer.parseInt(c2 + "") + Integer  
  108.                                     .parseInt(c1 + ""))));  
  109.                         }  
  110.                           
  111.                     } else if ("-".equals(ch)) {  
  112.                         if(c1.contains(".")||c2.contains(".")){  
  113.                         s.push(String.valueOf((Double.parseDouble(c2 + "") - Double  
  114.                                 .parseDouble(c1 + ""))));  
  115.                         }  
  116.                         else{  
  117.                             s.push(String.valueOf((Integer.parseInt(c2 + "") - Integer  
  118.                                     .parseInt(c1 + ""))));  
  119.                         }  
  120.                     } else if ("*".equals(ch)) {  
  121.                         if(c1.contains(".")||c2.contains(".")){  
  122.                         s.push(String.valueOf((Double.parseDouble(c2 + "") * Double  
  123.                                 .parseDouble(c1 + ""))));  
  124.                         }  
  125.                         else{  
  126.                             s.push(String.valueOf((Integer.parseInt(c2 + "") * Integer  
  127.                                     .parseInt(c1 + ""))));  
  128.                         }  
  129.                     } else if ("/".equals(ch)) {  
  130.                         s.push(String.valueOf((Double.parseDouble(c2 + "") / Double  
  131.                                 .parseDouble(c1 + ""))));  
  132.                     }  
  133.   
  134.                 } else {  
  135.                     System.out.println("式子有问题!");  
  136.                     return null;  
  137.                 }  
  138.             }  
  139.         }  
  140.         return s.pop();  
  141.     }  
  142. }