栈&栈的应用

来源:互联网 发布:华师大公共数据库密码 编辑:程序博客网 时间:2024/06/06 02:33

关于数据结构栈的相关应用,有以下几个任务需要我们完成。

1.动态顺序栈的实现

#include<iostream>using namespace std;template <class T>class Stack{public:Stack(){_capacity = 0;_size = 0;_array = NULL;}~Stack(){if (_array != NULL){delete[] _array;_array = NULL;}}void Push(const T& data){CheckCapacity();//一定要有内存空间才可以压栈_array[_size] = data;_size++;}void Pop(){if ((_array != NULL) && (_size != 0)){_size--;}}T& Top(){if ((_array != NULL) && (_size != 0)){return _array[_size - 1];}else{int t = -1;return t;}}T& Top()const//对top函数内的成员变量不能修改{if ((_array != NULL) && (_size != 0)){return _array[_size - 1];}else{int t = -1;return t;}}size_t Size()const{return _size;}bool Empty()const//判空{if ((_array != NULL) && (_size != 0)){return false;}elsereturn true;}private:void CheckCapacity()//检查并扩容{if (_capacity == _size){if (_array == NULL){_array = new T[2 * _capacity + 1];}else{T* temp = new T[2 * _capacity + 1];int pos = 0;while (pos < _size){temp[pos] = _array[pos];pos++;}delete[] _array;_array = temp;}_capacity = 2 * _capacity + 1;}}T* _array;//栈用数组实现,定义数组,size_t _capacity;//定义容量size_t _size;//size_t相当于unsigned int,定义大小};int main(){Stack<int>S;cout << S.Size() << endl;S.Push(1);S.Push(2);S.Push(3);S.Push(4);cout << S.Size() << endl;cout << S.Top() << endl;cout << S.Size() << endl;cout << S.Empty() << endl;S.Pop();S.Pop();S.Pop();S.Pop();S.Pop();cout << S.Size() << endl;cout << S.Top() << endl;cout << S.Empty() << endl;return 0;}
程序运行结果:


2.栈之应用--括号匹配

做题思想:括号匹配主要有两种情况

                   左括号多于右括号、右括号多于左括号、次序匹配不成功、匹配成功

(1)当字符串为空时,直接返回true;

(2)当字符串不为空时,开始遍历字符串。遇到非“(”、“)”、“[”、“]”、“{”、“}”这些括号时,让字符串继续往后遍历,直到遇到括号(或字符串遍历结             束)。定义一个栈,将左括号压栈,遇到右括号时,令栈顶的左括号与该右括号进行匹配。

         当栈为空时,说明右括号多于左括号;

         当字符串遍历结束后,栈不为空,说明左括号多于右括号;

         当右括号与栈顶的左括号不匹配时,说明次序不匹配

         当每次遍历的右括号都和栈顶的左括号匹配,并且栈内为空,字符串遍历结束,说明括号匹配成功。

程序代码:

#include<iostream>using namespace std;#include<stack>bool MatchBrackets(char* pStr){if (pStr == NULL){return true;}else{stack<char> s;char* str = pStr;while (*str != '\0')//遍历--判断str是否为空,如果不为空就可以进行括号匹配的问题检测{if ((*str == '(') || (*str == ')') || (*str == '[') || (*str == ']')\|| (*str == '{') || (*str == '}'))//如果在遍历过程中遇到这几种情况,则说明是括号,可以进行下面的判断{if ((*str == '(') || (*str == '[') || (*str == '{'))//左括号,压栈{s.push(*str);str++;}else//右括号与左括号匹配{if (s.empty()){return false;//左括号少于右括号}else{if ((s.top() == '(' && (*str == ')')) || (s.top() == '[' \&& (*str == ']')) || (s.top() == '{' && (*str == '}'))){s.pop();str++;}else//次序匹配不成功return false;}}}else//当不是括号时str++;}if (!s.empty())//左多于右{return false;}elsereturn true;}}int main(){char array[] = "((asg{[l]";//   0cout << MatchBrackets(array) << endl;char array1[] = "((asg{[l]}))";//   1cout << MatchBrackets(array1) << endl;char array2[] = "asg{[l]]]]";//   0cout << MatchBrackets(array2) << endl;char array3[] = "((asg{[l]]))";//   0cout << MatchBrackets(array3) << endl;return 0;}
运行结果:


3.栈之应用--计算后缀表达式

(1)在计算后缀表达式时,我们需要将平时常用的中缀表达式转换成后缀表达式。(在这里给大家介绍一下前中后缀表达式的区别)


上面是一个简单的后缀解释,后缀表达式中还有一些比较复杂的情况。如下图


下面,我们用代码实现以下这个过程

#include<iostream>#include<string>#include<stack>#include<vector>using namespace std;int Find(char c){if (c == '*' || c == '/')return 2;  // *、/ 优先级给2else if (c == '+' || c == '-')return 1; //+、- 优先级给1elsereturn 0;  // (、)、数字返回0}string InFix2PostFix(string s1, int size){string s; //后缀字符串if (s1.size() == 0)return s;  //返回空的后缀字符串else{stack<char> str;for (int i = 0; i < size; i++){if (Find(s1[i]) == 0 && s1[i] != '('&& s1[i] != ')')  //字符为数字,直接插入到后缀字符串中{s.push_back(s1[i]);}else{  //字符不是数字if (str.empty())str.push(s1[i]);  //字符栈为空,直接压栈else{if (s1[i] == '(')  //字符为左括号,直接压栈str.push(s1[i]);else if (s1[i] == ')') // 字符为右括号,将栈中左括号之后的字符全部插入到后缀字符串中并出栈{while (str.top() != '('){s.push_back(str.top());str.pop();}str.pop();  //删除左括号}else{  //字符为运算符 while (!str.empty() && Find(s1[i]) <= Find(str.top()) && str.top() != '(')  //与字符栈顶运算符优先级进行对比//比该遍历字符优先级高或者相同的栈顶元素插入到后缀字符串中,同时出栈{s.push_back(str.top());str.pop();}str.push(s1[i]);  //将遍历字符压入字符栈中}}}}while (!str.empty())  //保证字符栈为空,不为空时,将字符弹出并插入到后缀字符串中{s.push_back(str.top());str.pop();}return s;  //返回后缀字符串}}int main(){string s;cout << "请输入正确的中缀表达式:";cin >> s;string s1 = InFix2PostFix(s, s.size());cout << "后缀表达式为:" << s1 << endl;return 0;}
运行结果:


(2)将中缀表达式转换为后缀表达式以后,我们就来计算后缀表达式

下面是后缀表达式的一个计算过程


接下来用代码实现以下这个过程

#include<iostream>using namespace std;#include<stack>int CalcRPN(string str,int size){stack<int>s;if (str.empty())return 0;else{for (int i = 0; i < size; i++){if (str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/'){int num1 = s.top(); s.pop();int num2 = s.top();s.pop();switch (str[i]){case '+':s.push(num2 + num1);break;case '-':s.push(num2 - num1);break;case '*':s.push(num2*num1);break;case '/':s.push(num2 / num1);break;}}else{s.push(str[i]);}}}return s.top();}int main(){string str;str.push_back(12);str.push_back(3);str.push_back(4);str.push_back('+');str.push_back('*');str.push_back(6);str.push_back('-');str.push_back(8);str.push_back(2);str.push_back('/');str.push_back('+');cout << CalcRPN(str, str.size()) << " " << endl;return 0;}
运行结果:


原创粉丝点击