中缀转后缀及表达式求值

代码。。。。

/*
    参考:http://www.nowamagic.net/librarys/veda/detail/2306
         http://blog.youkuaiyun.com/geekcoder/article/details/6829386
         http://blog.youkuaiyun.com/mvpsendoh/article/details/6440559
         虽说是参考,可是受作者思路影响,里面相同的地方还是太多了= =。
*/
#include <iostream>
#include <stack>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>

#define ENDCHAR '#'

using namespace std;

//中缀转后缀部分
int isOperator(char c)
{
    switch(c)
    {
        case '+':
        case '-':
        case '*':
        case '/':
        case '%':
        case '^':
            return 1;        
        default:
            return 0;
    }
}

int priority(char c)
{
    switch(c)
    {
        case ENDCHAR:
        case '(':
            return 0;
        case '+':
        case '-':
            return 1;
        case '%'://坑爹了。。学了这么久,今天终于知道求模跟乘除是同一优先级
        case '*':
        case '/':
            return 2;
        case '^':
            return 4;
        default:
            cout << "Invalid Operator!: '" << c << "'" << endl;
            exit(1);
    }
}

void popAll(stack<char>&stk, char postfix[], int postIndex)
{
    while(stk.size() != 0)
    {
        postfix[postIndex++] = stk.top();
        stk.pop();
    }
    postfix[--postIndex] = '\0'; //在'#'处插入结束符
}

void infix2postfix(char infix[], char postfix[])
{
    int inIndex = 0, postIndex = 0;
    stack<char>operators;
    operators.push(ENDCHAR);//压入ENDCHAR避免后面操作到空栈而出错
    while(infix[inIndex])
    {
        if(isdigit(infix[inIndex]) || infix[inIndex] == '.') //数字直接输出到postfix中
        {
            postfix[postIndex++] = infix[inIndex];
        }
        else if(infix[inIndex] == '(')
        {
            //'(' 入栈
            operators.push(infix[inIndex]);
        }
        else if(infix[inIndex] == ')')   //括号与运算符分开处理
        {
        /*
            当当前符号为')'
            则依次弹出栈中符号直至遇到'('
        */
            while(operators.top() != '(')
            {
                postfix[postIndex++] = operators.top();
                operators.pop();
            }
            operators.pop();  //弹出'('
        }
        else if(isOperator(infix[inIndex]))
        {
        /*
            将当前操作符与栈顶操作符比较
            若小于等于栈顶操作符
            则将栈顶操作符弹出直至当前操作符大于栈顶操作符
            最后将当前操作符入栈
        */
            postfix[postIndex++] = ' ';  //隔开操作数
            while(priority(infix[inIndex]) <= priority(operators.top()))
            {
                postfix[postIndex++] = operators.top();
                operators.pop();
            }
            operators.push(infix[inIndex]);
        }
        ++inIndex;
    }
    popAll(operators, postfix, postIndex);//全部操作符出栈
}

//表达式求值部分
double calc(double num1, double num2, char op)
{
    switch(op)
    {
        case '+':return num1 + num2;
        case '-':return num1 - num2;
        case '*':return num1 * num2;
        case '/':return num1 / num2;
        case '%':return fmod(num1, num2);
        case '^':return pow(num1, num2);
        default:
            exit(1);
    }
}

double readNumber(char **string)
{
    double intNumber = 0;
    double floatNumber = 0;
    int times = 1;
    while(isdigit(**string))
    {
        intNumber = intNumber * 10 + **string - '0';
        ++*string;
    }
    if(**string == '.')
    {
        ++*string;
        while(isdigit(**string))
        {
            floatNumber = floatNumber + (**string - '0') * pow(0.1, times);
            ++*string;
        }
    }
    return intNumber + floatNumber;
}

double calcPostfix(char postfix[])
{
    double num1, num2;
    stack<double>numbers;
    while(*postfix)
    {
        if(isdigit(*postfix))
        {
            numbers.push(readNumber(&postfix));//读取数字
        }
        else if(isOperator(*postfix))
        {   
        /*
            取得2操作数
            执行当前运算并将结果入栈
        */
            num2 = numbers.top();
            numbers.pop();
            num1 = numbers.top();
            numbers.pop();
            numbers.push(calc(num1, num2, *postfix++));
        }
        else if(isspace(*postfix))
        {
            ++postfix; //跳过空格
        }
    }
    return numbers.top();
}

int main()
{
    char infix[100] = "", postfix[100] = "";
    while(1)
    {
        cout << "Input:";
        cin >> infix;
        infix2postfix(infix, postfix);
        cout << "Postfix:" << postfix << endl;
        cout << "Value:" << calcPostfix(postfix) << endl;
    }
    return 0;
}

运行截图。。。


总结。。。

终于知道%*/是同一优先级了。。。。尴尬

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值