中綴轉後綴及表達式求值

代碼。。。。

/*
    參考:http://www.nowamagic.net/librarys/veda/detail/2306
         http://blog.csdn.net/geekcoder/article/details/6829386
         http://blog.csdn.net/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;
}

運行截圖。。。


總結。。。

終於知道%*/是同一優先級了。。。。尷尬

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章