2、 栈、队列
背景知识:栈和队列的逻辑定义、存储定义和基本操作的实现及应用
目的要求:
- 掌握栈、队列的思想及其存储实现;
- 掌握栈、队列的常见算法的程序实现及应用。
实验内容: - 利用栈和算符优先算法,实现表达式求值。
- 采用顺序存储实现循环队列的初始化、入队、出队和求队列长度的操作。
实验步骤: - 从键盘输入表达式,求值,并显示求值结果;
- 每次入队或出队操作后,显示队列情况和队列长度。
测试数据:
(1)3×6+9-5×(8-3)
(2)循环队列大小为11;d,e,b,g,h入队;两次出队; i,j,k,l,m入队;一次出队; n,o,p,q,r入队
栈实现表达式求值
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int read() {int x; cin >> x; return x;}
template<typename T> struct stack
{
int top_ = 0;
T *a = 0;
void push(T x) {
top_++;
a = (T *)realloc(a,top_*sizeof(T));
a[top_-1] = x;
}
int size() {return top_;}
void pop() {top_--;}
T top() {return a[top_-1];}
bool empty(){return top == 0;}
T operator [] (int x){return a[x];}
};
char map[7]{'+','-','*','/','(',')','#'};
int mapT[1000];
int cmp[7][7] = {
1,1,-1,-1,-1,1,1,
1,1,-1,-1,-1,1,1,
1,1,1,1,-1,1,1,
1,1,1,1,-1,1,1,
-1,-1,-1,-1,-1,0,999,
1,1,1,1,999,1,1,
-1,-1,-1,-1,-1,999,0
};
const int maxn = 1e4+10;
int cntNum(int x)
{
int cnt = 1;
while(x/10) x/=10,cnt++;
return cnt;
}
char s[maxn];
int doit()
{
int len;
for(len = 0; s[len]; len++); s[len-1] = '#';
puts("________________________________________________________________________________________________________________");
puts("步骤--------------------OPTR栈--------------------OPND栈--------------------输入字符--------------------主要操作");
puts("________________________________________________________________________________________________________________");
stack<char> OPTR;stack<int> OPND;
OPTR.push('#');
int kase = 0;
for(int i = 0; i < len; i++){
printf("%2d",++kase);
for(int i = 0; i < 18; i++) putchar(' ');
for(int i = 0; i < OPTR.size(); i++) putchar(OPTR[i]);
for(int i = 0; i < 26-OPTR.size(); i++) putchar(' ');
int cnt = 0;
for(int i = 0; i < OPND.size(); i++) cout << OPND[i] << ' ',cnt += cntNum(OPND[i])-1;
for(int i = 0; i < 26-2*OPND.size()-cnt; i++) putchar(' ');
printf("%s",s+i);
for(int _ = 0; _ < 26-len+i; _++) putchar(' ');
if('0' <= s[i] && s[i] <= '9'){
int x = s[i]^48;
while(++i < len && '0' <= s[i] && s[i] <= '9') x = (x<<3)+(x<<1)+(s[i]^48);
printf("PUSH(OPND,%d)\n",x);
OPND.push(x);
i--;
continue;
}
if(cmp[mapT[OPTR.top()]][mapT[s[i]]]==1){
int a = OPND.top();OPND.pop();
int b = OPND.top();OPND.pop();
int x;
switch(OPTR.top())
{
case '+': x = b+a;break;
case '-': x = b-a;break;
case '*': x = b*a;break;
case '/': x = b/a;break;
}
printf("operate(%d,%c,%d)\n",b,OPTR.top(),a);
OPND.push(x);
OPTR.pop();
i--;
continue;
}
if(cmp[mapT[OPTR.top()]][mapT[s[i]]] == -1){
OPTR.push(s[i]);
printf("PUSH(OPTR,%c)\n",s[i]);
continue;
}
if(s[i] == '#' && OPTR.top() == '#'){
puts("RETURN(GETTOP(OPND))");
puts("________________________________________________________________________________________________________________");
return OPND.top();
}
if(cmp[mapT[OPTR.top()]][mapT[s[i]]] == 0){
OPTR.pop();
printf("POP\n");
continue;
}
}
}
int main()
{
/*
for(int i = 0; i < 7; i++){
for(int j = 0; j < 7; j++){
putchar(map[i]);
putchar(cmp[i][j]==1?'>':cmp[i][j]==-1?'<':cmp[i][j]==0?'=':' ');
putchar(map[j]);
putchar(' ');
}
putchar('\n');
}
*/
mapT['+'] = 0;mapT['-'] = 1;mapT['*'] = 2;
mapT['/'] = 3;mapT['('] = 4;mapT[')'] = 5;mapT['#'] = 6;
printf("按格式输入表达式(括号为英文括号,数字前不能有前导负号)\n例如:3*6+9-5*(8-3)\n");
fgets(s,maxn,stdin);
cout << "the answer is : " << doit() << endl;
return 0;
}
测试:
队列入队出队操作
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int read() {int x; cin >> x; return x;}
const int maxsize = 11;
template<typename T> struct queue
{
int flag = 0;
T a[maxsize];
int ft = 0,rear = 0;
void push(T x){
if(flag) {
printf("队满,%c入队失败\n",x);
exit(0);
}
ft = (ft+1)%maxsize;
if(ft == rear) flag = true;
a[ft] = x;
}
void pop() {
if(flag == 0 && ft == rear) {puts("队空,操作失败");exit(0);}
rear = (rear+1)%maxsize;
flag = false;
}
T front() {
if(flag == 0 && ft == rear) {puts("队空,操作失败");exit(0);}
return a[(rear+1)%maxsize];
}
bool empty() {return flag;}
int size() {
if(flag) return maxsize;
return (ft+maxsize-rear)%maxsize;
}
};
int main()
{
void print();
queue<char> Q;
while(1){
print();
int opt = read();
if(opt == 3) break;
if(opt == 1){
printf("输入入队元素个数: ");
int n = read();
printf("\n依次输入%d个元素: ",n);
while(n--){
char ch;
cin >> ch;
Q.push(ch);
}
}
else {
printf("输入出队元素个数: ");
int n = read();
while(n--){
cout << Q.front() << ' ';
Q.pop();
}
putchar('\n');
}
}
return 0;
}
void print()
{
puts("请选择操作");
puts("1、入队");
puts("2、出队");
puts("3、退出");
puts("");
}
测试: