1 #include<iostream>
2
3 using namespace std;
4
5 //栈的操作:初始化 push(插入) pop(弹栈,注意有的语言里的栈pop的时候会顺便返回top元素) top(看栈顶元素)
6 //用数组做栈,如果以起始位置作为栈顶的话,操作时候会引起大量数据的移动,不划算
7 //所以在用数组做栈的时候,会以末尾作为栈顶,起始位置作为栈底
8 //用链表做栈的时候,显然是与表头操作比较方便,所以链栈会用头作为栈顶
9 //C++ 中用stack利用栈 JAVA中用 Stack这个类
10 /*
11 C++:
12 #include<stack>
13 stack<int> st;
14 st.push(11);
15 st.push(22);
16 int x;
17 st.top();//返回是返回的一个引用 避免拷贝用内存过多
18 st.pop();//只弹栈
19 st.empty();
20 */
21
22 //顺序栈
23 struct Stack{
24 int *data;//动态分配内存 不固定大小 int data[100](固定)
25 int capacity;
26 int top;
27 };
28
29 void init(struct Stack *ps, int capacity){
30 //指向一个栈的指针 容量
31
32 ps->capacity = capacity;
33 //总大小 = int * capacity 没毛病
34 ps->data = malloc(sizeof(int) * capacity);
35 ps->top = 0;
36 //-1 和 0都可以 指向最高元素或者最高元素再往上的空位置
37 //但是-1和0会导致后面的操作会有所不同 注意
38
39 }
40
41 //因为多个函数要用到判断栈满 所以写为一个函数
42 bool isFull(const struct Stack *ps){
43 return ps->top == ps->capacity;//因为top = 0
44 }
45
46 bool push(struct Stack * ps, int data){
47 //异常判断 栈满
48 if(isFull(ps)) return false;
49 else{
50 //因为top = 0
51 ps->data[ps->top] = data;
52 //注意 这里能看出 栈顶在top - 1的位置
53 top ++;
54 return true;
55 }
56 }
57
58 //栈空时候不成功
59 //为什么非得写一个函数?
60 //我们写一个程序,里面的东西是作为接口提供给别人调用的
61 //别人只需要调用这个函数就行 内部细节不用给别人展现
62 bool isEmpty(const struct Stack *ps){
63 return ps->top == 0;
64 }
65
66 bool pop(struct Stack *ps, int *px){
67 //栈空
68 if(isEmpty(ps)) return false;
69 else{
70 //top = 0; 栈顶元素在top-1的位置
71 ps->top --;
72 *px = ps->data[ps->top];
73 return true;
74 }
75 }
76 //查看栈顶元素
77 int top(const struct Stack *ps, int *px){
78 //栈空
79 if(isEmpty(ps)) return 0;
80 else{
81 //top = 0; 栈顶元素在top-1的位置
82
83 *px = ps->data[ps->top - 1];
84 //*px是x的内容,已经把栈顶元素数据赋值给main中的x了,return只是表明是否获取成功
85 return 1;
86 }
87 }
88
89 void destroy(struct Stack *ps){
90 //只有data是malloc的
91 free(ps->data);
92 }
93
94 /***写函数 先写调用 再根据调用写具体内容***/
95 int main(){
96 struct Stack st;
97 //初始化
98 init(&st, 5);//要改变内容 所以要传地址; 多大
99 //压栈
100 push(&st, 11);//栈;元素数据
101 //弹栈 有两种,一种只负责弹出栈顶元素;另一种除了弹出还要返回弹出的值
102 //top()这个去查看栈顶元素
103 int x;//获取弹出值
104 pop(&st, &x);
105 top(&st, &x);
106 destroy(&st);
107 /***记得free!!!防止内存泄露 但是main中写也有问题 这样就是把细节展现在外面了***/
108 return 0;
109 }
110
111 **实例**后缀式求值
112 科普运算:运算符在运算数的位置中 后 前
113 中缀式:3+5*2
114 后缀式(逆波兰式) 352*+
115 前缀式(波兰式) +3*52
116
117 后缀式求值的思路:看见一个运算数,没有办法,先放一下,最终看见了运算符,可以做运算了
118 运算的运算数哪里来,就是前面的两个数.
119 例如:3 5 2 1 - * +,读 3 5 2 1 都没有处理方法,先晾着,然后读到了-,我们就可以做运算了,
120 那么要做运算的话,我们就需要运算数,运算数从哪里来啊,又因为是一个二元运算符,就前面拿来两个运算数,
121 这个操作就有点像栈,栈先存下了数字,到了运算符,就弹出.
122
123 题目:根据后缀式求值
124 输入样例:3 5.4 2.2 * +
125 输出样例:14.9
126
127 py实现代码
128
129 //函数计算
130 def cal(x, y, op):
131 if op == '+':
132 return x + y
133 else if op == '-'
134 return x - y
135 else if op == '*'
136 return x * y
137 else if op == '/'
138 return x / y
139
140 exp = input().split() //输入表达式并把每个字符分割 如3 5.5 + 2 / 会分割为一个列表['3' '5.5' '+' '2' '/']
141 st = list() //创建栈
142 for i in exp:
143 if i in '+-*/'://碰到运算符就退出
144 b = st.pop()
145 a = st.pop()
146 st.append(cal(a, b, i))
147 else://不是运算符就压栈
148 st.append(float(i))
149
150 print('%.lf' % st.pop())