1. 表达式计算:通过输入一组表达式,计算出结果。
例:( 5 + 7 * 3 ) / 4 + ( 5 + ( 4 - 3 ) * 2 ) = 13.50
2. 方法实现:
- 把表达式进行后序排列:
- 扫描表达式,遇见数字, 把数字传列表 list。
- 遇见符号,压入栈 stack 中,并进行一些列比较。
- 通过后序排列实现计算:
- 扫描列表 list, 遇见数字压入栈 stack 中。
- 遇见符号,从栈 stack 中取出两个数字进行运算。
- 取出列表 list 中的唯一数字,为此表达式的解。
后序排列实现:
给符号赋予优先级: (+, -) = 1, (*, /) = 2, { = 3, # = 0
- 在栈中先压入 "#"
- 扫描表达式,数字直接传个列表 list
- 比较栈中的符号和要扫描到的符号的优先级:
当栈中的符号优先级 >= 扫描到的优先级,把栈中的符号 pop 给列表 list,再循环比较剩下栈中的符号, 比较完成把扫描到的符号压入栈中。
注意:比较时如果栈中符号是 ‘{’,则终止比较。如果扫描到的符号是 ‘}’, 则把栈中的符号 pop 给列表 list 直到匹配到 ‘{’。如果扫描到的符号是 ‘#’, 则把栈中的符号全部 pop 给列表 list 直到匹配到 ‘#’。
代码实现:
#include<stdio.h>
#include<string.h>
// 1. 创建栈 Stack
struct STACK
{
char stack[40];
int top;
}Stack;
// 2. 出栈操作
char stackPop()
{
char x = Stack.stack[Stack.top-1];
Stack.top --;
return x;
}
// 3. 入栈操作
void stackAppend(char x)
{
Stack.stack[Stack.top] = x;
Stack.top ++;
}
// 4. 设置优先级
int priority(char x)
{
if(x == '+' || x == '-')
return 1;
else if(x == '*' || x == '/')
return 2;
else if(x == '(')
return 3;
else
return 0;
}
int main()
{
int i = 0, j = 0;
char b;
// 创建列表 list
char list[40];
char x[40];
Stack.stack[0] = '#';
Stack.top = 1;
scanf("%s", x);
// 末尾添加‘#’
strcat(x, "#");
// 2. 扫描
while(x[i] != '\0')
{
// 3. 数字直接传到 list 中
if(x[i] >= '0' && x[i] <= '9'){
list[j] = x[i];
j ++;
}
// 4. 比较字符
else
{
// 如果是‘)’,则直接 pop 到 list 中直到‘(’
if(x[i] == ')'){
b = stackPop();
while(b != '('){
list[j] = b;
j ++;
b = stackPop();
}
}
// 如果是‘#’,则直接 pop 到 list 中直到‘#’
else if(x[i] == '#'){
b = stackPop();
while(b != '#'){
list[j] = b;
j ++;
b = stackPop();
}
}
else{
b = stackPop();
while(priority(b) >= priority(x[i]) && b != '('){
list[j] = b;
j ++;
b = stackPop();
}
stackAppend(b);
stackAppend(x[i]);
}
}
i++;
}
for(i=0; i<j; i++){
printf("%c", list[i]);
}
printf("\n");
}
计算:
扫描链表,遇到数字时压入栈中,遇到字符时从栈中取出两个数字,进行运算,再压入栈中,最后取出栈中的元素,为最后的值。
// 计算的栈,小数
struct count_stack
{
double stack[20];
int top;
}ct_stack;
double ct_stackPop()
{
double x = ct_stack.stack[ct_stack.top-1];
ct_stack.top --;
return x;
}
void ct_stackAppend(double x)
{
ct_stack.stack[ct_stack.top] = x;
ct_stack.top ++;
}
void countList(char *list, int j)
{
int i;
double a, b;
ct_stack.top = 0;
for(i=0; i<j; i++)
{
if(list[i] >= '0' && list[i] <= '9'){
ct_stackAppend(list[i] - '0');
}else{
a = ct_stackPop();
b = ct_stackPop();
if(list[i] == '+')
ct_stackAppend(a + b);
else if(list[i] == '-')
ct_stackAppend(b - a);
else if(list[i] == '*')
ct_stackAppend(a * b);
else
ct_stackAppend(1.0*b/a);
}
}
printf("%.2f", ct_stack.stack[0]);
printf("\n");
}
代码实现:
c语言:
#include<stdio.h>
#include<string.h>
// 1. 创建栈 Stack
struct STACK
{
char stack[40];
int top;
}Stack;
void countList(char *, int);
// 2. 出栈操作
char stackPop()
{
char x = Stack.stack[Stack.top-1];
Stack.top --;
return x;
}
// 3. 入栈操作
void stackAppend(char x)
{
Stack.stack[Stack.top] = x;
Stack.top ++;
}
// 4. 设置优先级
int priority(char x)
{
if(x == '+' || x == '-')
return 1;
else if(x == '*' || x == '/')
return 2;
else if(x == '(')
return 3;
else
return 0;
}
int main()
{
int i = 0, j = 0;
char b;
// 创建列表 list
char list[40];
char x[40];
Stack.stack[0] = '#';
Stack.top = 1;
scanf("%s", x);
// 末尾添加‘#’
strcat(x, "#");
// 2. 扫描
while(x[i] != '\0')
{
// 3. 数字直接传到 list 中
if(x[i] >= '0' && x[i] <= '9'){
list[j] = x[i];
j ++;
}
// 4. 比较字符
else
{
// 如果是‘)’,则直接 pop 到 list 中直到‘(’
if(x[i] == ')'){
b = stackPop();
while(b != '('){
list[j] = b;
j ++;
b = stackPop();
}
}
// 如果是‘#’,则直接 pop 到 list 中直到‘#’
else if(x[i] == '#'){
b = stackPop();
while(b != '#'){
list[j] = b;
j ++;
b = stackPop();
}
}
else{
b = stackPop();
while(priority(b) >= priority(x[i]) && b != '('){
list[j] = b;
j ++;
b = stackPop();
}
stackAppend(b);
stackAppend(x[i]);
}
}
i++;
}
for(i=0; i<j; i++){
printf("%c", list[i]);
}
printf("\n");
// 计算
countList(list, j);
}
struct count_stack
{
double stack[20];
int top;
}ct_stack;
double ct_stackPop()
{
double x = ct_stack.stack[ct_stack.top-1];
ct_stack.top --;
return x;
}
void ct_stackAppend(double x)
{
ct_stack.stack[ct_stack.top] = x;
ct_stack.top ++;
}
void countList(char *list, int j)
{
int i;
double a, b;
ct_stack.top = 0;
for(i=0; i<j; i++)
{
if(list[i] >= '0' && list[i] <= '9'){
ct_stackAppend(list[i] - '0');
}else{
a = ct_stackPop();
b = ct_stackPop();
if(list[i] == '+')
ct_stackAppend(a + b);
else if(list[i] == '-')
ct_stackAppend(b - a);
else if(list[i] == '*')
ct_stackAppend(a * b);
else
ct_stackAppend(1.0*b/a);
}
}
printf("%.2f", ct_stack.stack[0]);
printf("\n");
}
python:
class Stack():
def __init__(self):
self.list = [0] * 20
self.list[0] = '#'
self.top = 1
def stackPop(self):
a = self.list[self.top-1]
self.list[self.top-1] = 0
self.top -= 1
return a
def stackAppend(self, index):
self.list[self.top] = index
self.top += 1
stack = Stack()
a = input().split()
a.append('#')
b = []
def priority(x):
if x == '-' or x == '+':
return 1
elif x == '*' or x == '/':
return 2
elif x == '#':
return 0
for i in a:
try:
i = int(i)
print(i, end=" ")
b.append(i)
except:
if i == '#':
x = stack.stackPop()
while x != '#':
print(x, end="")
b.append(x)
x = stack.stackPop()
elif i == '(':
stack.stackAppend(i)
elif i == ')':
x = stack.stackPop()
while x != '(':
print(x, end=" ")
b.append(x)
x = stack.stackPop()
else:
x = stack.stackPop()
try:
while priority(x) >= priority(i):
print(x, end=" ")
b.append(x)
x = stack.stackPop()
stack.stackAppend(x)
stack.stackAppend(i)
except:
stack.stackAppend(x)
stack.stackAppend(i)
stack2 = Stack()
for i in b:
if isinstance(i, (int, float)):
stack2.stackAppend(i)
else:
x = stack2.stackPop()
y = stack2.stackPop()
if i == '+':
stack2.stackAppend(y + x)
elif i == '-':
stack2.stackAppend(y - x)
elif i == '*':
stack2.stackAppend(y * x)
else:
stack2.stackAppend(y/x)
print("\n%.2f" % stack2.list[1])
javascript:
function main()
{
// 后序排列
let x = "( 5 + 7 * 3 ) / 4 + ( 5 + ( 4 - 3 ) * 2 )" + ' #'
let list = []
var stack = ['#']
x = x.split(" ")
for(i of x){
if(! isNaN(parseInt(i))){
list.push(i)
}
else if(i == ')' ){
a = stack.pop()
while(a != '('){
list.push(a)
a = stack.pop()
}
}
else if(i == '#'){
a = stack.pop()
while(a != '#'){
list.push(a)
a = stack.pop()
}
}
else
{
a = stack.pop()
while(priority(a) >= priority(i) && a != '('){
list.push(a)
a = stack.pop()
}
stack.push(a)
stack.push(i)
}
}
console.log(list)
// 计算
for(i of list){
if(! isNaN(parseInt(i)))
stack.push(parseInt(i))
else{
a = stack.pop()
b = stack.pop()
if(i == '+')
stack.push(a+b)
else if(i == '-')
stack.push(b-a)
else if(i == '*')
stack.push(a*b)
else
stack.push(b/a)
}
}
console.log(Number(stack))
}
main()
function priority(x){
if(x == '+' || x == '-')
return 1
else if(x == '*' || x == "/")
return 2
else if(x == '(')
return 3
else
return 0
}