数据结构-栈的应用:表达式求值
数据结构-栈的应用:表达式求值
暂时只支持小于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;
}