栈(statck)这种数据结构在计算机中是相当出名的。栈中的数据是先进后出的(First In Last Out, FILO)。栈只有一个出口,允许新增元素(只能在栈顶上增加)、移出元素(只能移出栈顶元素)、取得栈顶元素等操作。在STL中,栈是以别的容器作为底部结构,再将接口改变,使之符合栈的特性就可以了。因此实现非常的方便。在STL中栈一共就5个常用操作函数(top()、push()、pop()、 size()、empty() ),很好记的。
#include <iostream> #include <vector> #include <stack> #include <list> using namespace std; int main() { //定义栈 使用list作为容器 stack<int,list<int>> a; stack<int,vector<int>> b; int i; //压入栈数据 for(i = 0;i < 10;i++) { a.push(i); b.push(i); } //输出栈size的大小 cout<<"a stack size : " << a.size()<<endl; //取栈项数据并将数据弹出栈 cout<<"a 中的数据:"; while(!a.empty()) { cout<<a.top()<<" "; //栈顶元素弹出栈 a.pop(); } cout<<endl; cout<<"b 中的数据:"; while(!b.empty()) { cout<<b.top()<<" "; //栈顶元素弹出栈 b.pop(); } system("pause"); return 0; }
栈的实践使用:逆波兰公式
对后缀表达式求值比直接对中缀表达式求值简单。在后缀表达式中,不需要括号,而且操作符的优先级也不再起作用了。您可以用如下算法对后缀表达式求值:
<pre name="code" class="cpp">#include <iostream> #include <stack> #include <list> using namespace std; //声明函数 bool isOperand(char c); bool isOpertor(char c); bool ComaprePriority(char op1,char op2); int getPriorityValue(char c); int Operate(char op, int operand1, int operand2); //判断是否为数字 bool isOperand(char c) { return ( c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9' ); } //判断是否为运算符 bool isOpertor(char c) { return ( c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' ); } //判断运算符优先级大小 op1优先级高于或者等于op2返回true bool ComaprePriority(char op1,char op2) { return (getPriorityValue(op1) >= getPriorityValue(op2)) ; } //获取运算符优先级 int getPriorityValue(char c) { int prioityValue; switch(c) { case '+ ': prioityValue = 1; break; case '-': prioityValue = 1; break; case '*': prioityValue = 2; break; case '/': prioityValue = 2; break; default: prioityValue = 0; } return prioityValue; } int Operate(char op, int operand1, int operand2) { switch(op) { case '+': return operand1 + operand2; case '-': return operand1 - operand2; case '*': return operand1 * operand2; case '/': return operand1 / operand2; default: return -1; } } int main() { //定义栈 使用list作为容器 stack<char> operand; stack<char> opertor; char str[20] = "(2+4)*4+1"; //压入栈数据 int length = strlen(str); for(int i = 0;i < length;i++) { char c = str[i]; cout<<c<<" "; //判断是否为操作数 if (isOperand(c)) { operand.push(c); } else { //为运算符 //若运算符为"("直接存入到运算符栈中 if( c == '(') { opertor.push(c); } else if(c == ')') { //该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止。 while(opertor.top() != '(') { char op = opertor.top(); opertor.pop(); operand.push(op); } //将'('出栈 opertor.pop(); } else { // 该运算符为非括号运算符: // (a) 若运算符堆栈栈顶的运算符为括号,则直接存入运算符堆栈。 //考虑栈顶为空的情况 if(opertor.empty()) { opertor.push(c); continue; } if(opertor.top() == '(') { opertor.push(c); } else { //(b) 若比运算符堆栈栈顶的运算符优先级高或相等,则直接存入运算符堆栈。 if(ComaprePriority(c,opertor.top())) { opertor.push(c); } else { // (c) 若比运算符堆栈栈顶的运算符优先级低,则输出栈顶运算符到操作数堆栈,并将当前运算符压入运算符堆栈。 char op = opertor.top(); operand.push(op); opertor.pop(); opertor.push(c); }// if(ComaprePriority(c,opertor.top())) }//end if(opertor.top() == '(') }//end if( c == '(') }//end if (isOperand(c)) }//end for //4、当表达式读取完成后运算符堆栈中尚有运算符时,则依序取出运算符到操作数堆栈,直到运算符堆栈为空。 while(!opertor.empty()) { char op = opertor.top(); operand.push(op); opertor.pop(); } //cout<<endl<<"转换后的逆波兰表达式:"; //输出转换后的逆波兰表达式 //while(!operand.empty()) //{ // cout<<operand.top()<<" "; // operand.pop(); //} //计算逆波兰表达式 stack<char> stackOper; stack<int> stackresult;//计算使用栈 //上面计算后的栈是反着的 把它倒转过来计算 while(!operand.empty()) { //cout<<operand.top()<<" "; char op = operand.top(); stackOper.push(op); operand.pop(); } //计算逆波兰表达式 while(!stackOper.empty()) { char op = stackOper.top(); //如果字符是一个操作数,把它压入堆栈。 if (isOperand(op)) { int num ; num = atoi(&op); stackresult.push(num); } else { //如果字符是个操作符,弹出两个操作数,执行恰当操作,然后把结果压入堆栈。如果您不能够弹出两个操作数,后缀表达式的语法就不正确。 int number1 = stackresult.top(); stackresult.pop(); int number2 = stackresult.top(); stackresult.pop(); //弹出两个操作符执行运算 int result = Operate(op,number1,number2); stackresult.push(result); } stackOper.pop(); } //输出计算结果 cout<<" = " << stackresult.top()<<endl; system("pause"); return 0; }