数据结构-栈的应用:表达式求值

数据结构-栈的应用:表达式求值

暂时只支持小于10的数之间的四则运算。

#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
typedef double ElemTypeA;
typedef char ElemTypeB;

typedef struct NodeA { ElemTypeA data; NodeA *next;} *StackA;
typedef struct NodeB { ElemTypeB data; NodeB *next;} *StackB;

bool InitStack(StackA &A) { A = new NodeA; if (!A) { printf("InitStack执行失败 "); return false; } A->next = NULL; return true; }
bool InitStack(StackB &B) { B = new NodeB; if (!B) { printf("InitStack执行失败 "); return false; } B->next = NULL; return true; }
bool Push(StackA &A, ElemTypeA x) { if (!A) { printf("Push执行失败 "); return false; } NodeA *s = new NodeA; s->data = x; s->next = A->next; A->next = s; return true; }
bool Push(StackB &B, ElemTypeB x) { if (!B) { printf("Push执行失败 "); return false; } NodeB *s = new NodeB; s->data = x; s->next = B->next; B->next = s; return true; }
bool Pop(StackA &A, ElemTypeA &x) { if (!A) { printf("Pop执行失败 "); return false; } if (!A->next) { printf("Pop执行失败 "); return false; } NodeA *p = A->next; x = p->data; A->next = p->next; delete p; return true; }
bool Pop(StackB &B, ElemTypeB &x) { if (!B) { printf("Pop执行失败 "); return false; } if (!B->next) { printf("Pop执行失败 "); return false; } NodeB *p = B->next; x = p->data; B->next = p->next; delete p; return true; }
ElemTypeA GetTop(StackA A) { if (!A) return -1; if (!A->next) return -1; return A->next->data; }
ElemTypeB GetTop(StackB B) { if (!B) return '\0'; if (!B->next) return '\0'; return B->next->data; }
bool Reverse(StackA &A) { if (!A) return false; NodeA *p = A->next, *q; if (!p) return false; while(p->next) { q = p->next; p->next = q->next; q->next = A->next; A->next = q; } return true;}
bool Reverse(StackB &B) { if (!B) return false; NodeB *p = B->next, *q; if (!p) return false; while(p->next) { q = p->next; p->next = q->next; q->next = B->next; B->next = q; } return true;}
void PrintStack(StackA A) { if (!A) return; A = A->next; printf("(栈顶) "); while(A) { printf("%.f ", A->data); A = A->next; } printf("\n"); }
void PrintStack(StackB B) { if (!B) return; B = B->next; printf("(栈顶) "); while(B) { printf("%c ", B->data); B = B->next; } printf("\n"); }

void Do(bool func, const ElemTypeB* msg) { if (!func) printf("Pop执行失败[%s] ", msg); }

bool isDigit(ElemTypeB x) { return x >= '0' && x <= '9'; }

double calc(const ElemTypeB* expr) {
    // A 操作数栈;B 操作符栈
    if (expr == "") return 0;
    double res = 0; ElemTypeB tmp = '\0';
    StackB ope, target; InitStack(ope); InitStack(target);

    // 形成后缀表达式 target
    for (int i = 0; i < strlen(expr); i++) {
        // 左括号  入符号栈 ope
        if (expr[i] == '(') Push(ope, expr[i]);
        // 数字    入操作数栈 target
        else if (isDigit(expr[i])) {
            if (i == 0) Push(target, expr[i]);
            else {
                int j = 1; double num = expr[i] - 48;
                while (j <= i)
                    if (isDigit(expr[i - j])) {
                        num += pow(10, j) * (expr[i - j++] - 48);
                        // printf("(%d) ", (int)num);
                    }
                    else break;
                Push(target, (int)num + 48);
            }
        }
        // 四则运算
        else if (expr[i] == '+' || expr[i] == '-') {
            if (GetTop(ope) == '+' || GetTop(ope) == '-' || GetTop(ope) == '*' || GetTop(ope) == '/') {
                Pop(ope, tmp); Push(target, tmp);
                if (GetTop(ope) == '+' || GetTop(ope) == '-') { Pop(ope, tmp); Push(target, tmp); }
            }
            Push(ope, expr[i]);
        }
        else if (expr[i] == '*' || expr[i] == '/') {
            if (GetTop(ope) == '*' || GetTop(ope) == '/') {
                Pop(ope, tmp); Push(target, tmp);
            }
            Push(ope, expr[i]);
        }
        else if (expr[i] == ')') {
            if (GetTop(ope) == '+' || GetTop(ope) == '-') { Pop(ope, tmp); Push(target, tmp); }
            else if (GetTop(ope) == '*' || GetTop(ope) == '/') {
                Pop(ope, tmp); Push(target, tmp);
                if (GetTop(ope) == '+' || GetTop(ope) == '-') { Pop(ope, tmp); Push(target, tmp); }
            }
            if (GetTop(ope) == '(') Pop(ope, tmp); else { printf("表达式出错请检查。"); return -1; }
        }
    }
    while (ope->next) { if (ope->next->data == '(') { printf("表达式出错请检查。"); return -1; } Pop(ope, tmp); Push(target, tmp); }

    Reverse(target);

    PrintStack(ope);
    PrintStack(target);
    double a1 = 0, a2 = 0; char tmp2; StackA resStack; InitStack(resStack);
    while(GetTop(target) != '\0') {
        Pop(target, tmp2);
        if (tmp2 == '+') { Pop(resStack, a2); Pop(resStack, a1); Push(resStack, a1 + a2); }
        else if (tmp2 == '-') {Pop(resStack, a2); Pop(resStack, a1); Push(resStack, a1 - a2); }
        else if (tmp2 == '*') {Pop(resStack, a2); Pop(resStack, a1); Push(resStack, a1 * a2); }
        else if (tmp2 == '/') {Pop(resStack, a2); Pop(resStack, a1); Push(resStack, a1 / a2); }
        else Push(resStack, tmp2 - 48);
    }

    return GetTop(resStack);
}

int main(int argc, char const *argv[])
{
    const char* expr = "4-5/5+5*5/5";
    printf("%s = %.f", expr, calc(expr));

    return 0;
}


posted @ 2021-09-02 10:56  hccodec  阅读(107)  评论(0编辑  收藏  举报