#include<iostream> using namespace std; constint N = 1e4+10; template <classT> classStack { public: boolempty() { return top == -1; } voidpush(T x) { a[++top] = x; } T pop() { return a[top--]; } T peak() { return a[top]; } private: int top = -1; T a[N]; };
Stack<int> NUM; Stack<char>OP; int p[100] = { 0 };//运算符优先级
voidoperation(Stack<int>&NUM, Stack<char>&OP)//将计算操作抽离出来 { char t = OP.pop(); int b = NUM.pop();//注意a,b顺序 int a = NUM.pop(); if (t == '+') NUM.push(a + b); elseif (t == '-')NUM.push(a - b); elseif (t == '*')NUM.push(a * b); else NUM.push(a / b); } intculculate(char* s) { int len = strlen(s); p['+'] = p['-'] = 1; p['*'] = p['/'] = 2;//定义优先级! for (int i = 0; i < len; i++) { if (s[i] >= '0' && s[i] <= '9')//操作数 { int tmp = 0; while (i < len && s[i] >= '0' && s[i] <= '9') tmp = 10 * tmp + s[i++] - '0'; NUM.push(tmp); i--;// } elseif (s[i] == '(') OP.push('(');//括号 elseif (s[i] == ')') { while (!OP.peak() == '(') operation(NUM, OP); OP.pop(); } else//操作符 { while (!OP.empty() && OP.peak() != '(' && !(p[s[i]] > p[OP.peak()]))//OP为空,遇到左括号,s[i]优先级大则不弹 { operation(NUM, OP); } OP.push(s[i]); } } while (!OP.empty()) operation(NUM, OP); return NUM.peak(); } intmain() { char a[] = "20+8*3"; cout<<culculate(a); }
栈混洗
栈混洗的甄别:判断是否为合法的出栈序列
1 2 3 4 5 6 7 8 9 10 11 12 13
boolcheck(int A[], int B[], int n) { Stack s; int k = 0;//通过k扫描入栈序列 for (int i = 0; i < n; i++)//通过i扫描出栈序列 { while (s.empty() || s.peak() != B[i]) if (k < n) s.push(A[k++]); elsereturnfalse; s.pop();//只有s.peak()==B[i]才弹栈 } returntrue; }
栈混洗的总数:有多少种可能的出栈序列
6个元素的栈混洗总数 入栈序列1,2…6可能的合法出栈序列数 6对括号的合法匹配序列数
队列的讨论及应用
实现
1 2 3 4 5 6 7 8 9 10
classqueue { public: int p[N]; int front=0; int rear=0; voidenqueue(int x){p[rear++]=x; } intdequeue(){ return p[front++];} boolempty(){return front==rear;} };