后缀表达式计算算术表达式


http://www.acmerblog.com/infix-to-postfix-6072.html

 

http://www.nowamagic.net/librarys/veda/detail/2306

 

代码分为3部分,我知道很丑,可以不看,主要看原理。

1、translator.h

        转换函数,先把 中缀表达式表达为后缀表达式

    

// 把中缀表达式 转换为 后缀表达式

#pragma  once
#include <string>
#include <stdio.h>
#include <stack>
using namespace std;
#include "util.h"


string  transform(string input)
{
    stack<char>  operandStack; // 操作符
    string rst;
    for (int i=0; i < input.length(); i++)
    {
        if ( isdigit(input[i]) )
        {
            // 放到结果里
             rst.push_back(input[i]);
        }
        else if(isCommonOperand(input[i]))
        {
            // 如果operandStack栈为空,不需要考虑优先级
            if (operandStack.empty())
            {
                operandStack.push(input[i]);
            }
            else
            {
                // 此处要考虑优先级
                    int r = getRank(input[i]);
                  // 与上一个操作符的优先级比较
                  // 若大,则入栈
                  if(r > getRank(operandStack.top()))
                  {
                       operandStack.push(input[i]);
                  }
                  // 若小于上一个的操作符,就要弹出直到operandStack栈为空或当前的操作符ch的优先级大于栈顶的操作符。
                  // 最后才将当前操作符入栈。
                  else{
                      while(!operandStack.empty() &&   r <= getRank(operandStack.top()))
                      {
                          rst.push_back(operandStack.top()); // 存到结果里
                          operandStack.pop();       
                      }
                     operandStack.push(input[i]);
                  }
            }
        }
        // 左括号也要入操作符栈
        else if(input[i] == '('){
           operandStack.push(input[i]);
        }
        // 右括号,比较特殊。操作符栈弹出,放到结果里。直至遇到左括号
        else if(input[i] == ')'){
              char top = operandStack.top();
              while(top != '('){
                        rst.push_back(top);
                        operandStack.pop();       
                         top = operandStack.top();
                     }
              operandStack.pop(); //把 ( 也要去掉
        }
        else {

        }
    }

    //  把剩余的操作符也加上
     while(!operandStack.empty()) 
     {
            rst.push_back(operandStack.top());
            operandStack.pop();
     }
    return rst;
}


 

 

2、calcuator.h

    计算函数,计算后缀表达式

    

// 把输入的后缀表达式 进行入栈 出栈 处理,进行真正的计算

#pragma  once
#include <string>
#include <stdio.h>
#include <stack>
using namespace std;
#include "util.h"


/*
从左至右扫描表达式,
遇到数字时,将数字压入堆栈,
遇到运算符时,弹出栈顶的两个数,
用运算符对它们做相应的计算(次顶元素 op 栈顶元素),
并将结果入栈;重复上述过程直到表达式最右端,
最后运算得出的值即为表达式的结果。
*/

float calc(string polan)
{
    float result;
    stack<float>  dataStack; // 操作数 临时存储地方
    float first = 0.0;
    float second = 0.0;
    for (int i=0; i < polan.length(); i++)
    {
        if ( isdigit(polan[i]) )
        {
            dataStack.push(polan[i] - '0');
        }
        else if(isCommonOperand(polan[i]))
        {
            second= dataStack.top();  //重要,因为先出来的是 位于计算式后面的
            dataStack.pop();
            first = dataStack.top();
            dataStack.pop();
            float tmp = doCal(first,second,polan[i]);
            dataStack.push (tmp);
        }
        else
        {

        }
    }
      result = dataStack.top();
      return result;
}


 

3、util.h

   提供公有函数

  

#pragma  once
#include <stdio.h>
#include <stack>
using namespace std;

bool isCommonOperand(char operand)
{
    switch (operand)
    {
    case '+' :
        return true;
    case  '-':
        return true;
    case '*':
        return true;
    case '/':
        return true;
    default:
        return false;
    }
    return false;
}

// 获取操作符C 的优先级
int getRank(char c)
{
    switch (c) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
    }
    return -1;
}

 float doCal(float first,float second,char oper)
 {
     switch (oper) {
            case '+':
                return first + second;
            case '-':
                return first - second;
            case '*':
                return first*second;
            case '/':
                return first/second;
     }
     return 0.0;
 }


 

4、main.cpp

   客户端,接受输入

 

#include "translator.h "
#include "calcuator.h"

#include <iostream>
#include <string>

using namespace std;

int main()
{
    //cout << "hello"  <<endl;
   // string inputStr =  "1+2-3/4+5*6";  //期望输出   12+34/-56*+
    // "(1+2)*3" 期望输出  12+3*
    cout << "please input your calc input:" <<endl;
    while (1)
    {
        char Buffer[100]; //从客户端接受的输入

        cout<<"请输入计算字符串:"<<endl;
        string str;

        char rechar[200];//接受从服务端返回的结果

        if(cin>>str)
        {
            if (str.find("q") != string::npos)
            {
                break;
            }
            string inputStr = str;
            string midStr = transform(inputStr);
            float result  =   calc(midStr);
             cout<<"结果输出为:"<<endl;
            cout << "result=" << result <<endl;
        }
       
    }
    return 0;
}


 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值