#include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define MAXSIZE 100 typedef double DataType; typedef enum symbol //字符枚举变量,用于getsym函数判断读入内容为数字,操作符,等号,还是其他 { NUM, OPE, EQU, OTH } SymType; typedef enum operator //操作符枚举变量,用于入栈及根据优先级数列判断优先级 { AND, XOR, OR, MORE, LESS, ADD, MIN, MUL, DIV, MOD, NOT, LEFT, RIGHT } OpeType; int prior[] = {0, -1, -2, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5}; union sym //联合变量,用于读取操作符或数字 { DataType num; OpeType op; }; OpeType Ope_Stack[MAXSIZE]; int OpeTop = -1; DataType Num_Stack[MAXSIZE]; int NumTop = -1; SymType GetSym(union sym *item); void Push_Ope(OpeType op); void Push_Num(DataType num); OpeType Pop_Ope(); DataType Pop_Num(); void operate(OpeType op); void calculate(OpeType op); int main() { union sym item; SymType s; while ((s = GetSym(&item)) != EQU) { if (s == NUM) Push_Num(item.num); else if (s == OPE) { operate(item.op); } else { printf("Error Input!\n"); return 1; } } while (OpeTop != -1) { calculate(Pop_Ope()); } if (NumTop == 0) printf("%g\n", Pop_Num()); else { printf("Error Input!\n"); return 1; } } SymType GetSym(union sym *item) { char c; while ((c = getchar()) != '=') { if (c >= '0' && c <= '9') { for (item->num = 0; c >= '0' && c <= '9'; c = getchar()) { item->num = item->num * 10 + c - '0'; } ungetc(c, stdin); return NUM; } else { switch (c) { case '&': item->op = AND; return OPE; case '^': item->op = XOR; return OPE; case '|': item->op = OR; return OPE; case '>': item->op = MORE; return OPE; case '<': item->op = LESS; return OPE; case '+': item->op = ADD; return OPE; case '-': item->op = MIN; return OPE; case '*': item->op = MUL; return OPE; case '/': item->op = DIV; return OPE; case '%': item->op = MOD; return OPE; case '!': item->op = NOT; return OPE; case '(': item->op = LEFT; return OPE; case ')': item->op = RIGHT; return OPE; case ' ': case '\t': case '\n': break; default: return OTH; } } } return EQU; } void Push_Ope(OpeType op) { if (OpeTop == MAXSIZE - 1) { printf("operator stack is full!\n"); exit(1); } Ope_Stack[++OpeTop] = op; return; } void Push_Num(DataType num) { if (NumTop == MAXSIZE - 1) { printf("number stack is full!\n"); exit(1); } Num_Stack[++NumTop] = num; return; } OpeType Pop_Ope() { if (OpeTop == -1) { printf("Error Input!\n"); exit(1); } return Ope_Stack[OpeTop--]; } DataType Pop_Num() { if (NumTop == -1) { printf("Error Input!\n"); exit(1); } return Num_Stack[NumTop--]; } void operate(OpeType op) { OpeType t; if (op == RIGHT) { while ((t = Pop_Ope()) != LEFT) calculate(t); } else { while (OpeTop != -1 && prior[op] <= prior[Ope_Stack[OpeTop]] && Ope_Stack[OpeTop] != LEFT) calculate(Pop_Ope()); Push_Ope(op); } } void calculate(OpeType op) { DataType temp; switch (op) { case AND: Push_Num((int)Pop_Num() & (int)Pop_Num()); break; case XOR: Push_Num((int)Pop_Num() ^ (int)Pop_Num()); break; case OR: Push_Num((int)Pop_Num() | (int)Pop_Num()); break; case MORE: temp = Pop_Num(); Push_Num(Pop_Num() > temp); break; case LESS: temp = Pop_Num(); Push_Num(Pop_Num() < temp); break; case ADD: Push_Num(Pop_Num() + Pop_Num()); break; case MIN: temp = Pop_Num(); Push_Num(Pop_Num() - temp); break; case MUL: Push_Num(Pop_Num() * Pop_Num()); break; case DIV: temp = Pop_Num(); Push_Num(Pop_Num() / temp); break; case MOD: temp = Pop_Num(); Push_Num((int)Pop_Num() % (int)temp); break; case NOT: Push_Num(!(int)Pop_Num()); break; } }
|