表达式计算(三种语言实现)

562 阅读4分钟

1. 表达式计算:通过输入一组表达式,计算出结果。

例:( 5 + 7 * 3 ) / 4 + ( 5 + ( 4 - 3 ) * 2 ) = 13.50

2. 方法实现:

  • 把表达式进行后序排列:
    • 扫描表达式,遇见数字, 把数字传列表 list。
    • 遇见符号,压入栈 stack 中,并进行一些列比较。
  • 通过后序排列实现计算:
    • 扫描列表 list, 遇见数字压入栈 stack 中。
    • 遇见符号,从栈 stack 中取出两个数字进行运算。
  • 取出列表 list 中的唯一数字,为此表达式的解。


后序排列实现:

给符号赋予优先级: (+, -) = 1, (*, /) = 2, { = 3, # = 0

  1. 在栈中先压入 "#"
  2. 扫描表达式,数字直接传个列表 list
  3. 比较栈中的符号和要扫描到的符号的优先级:
    当栈中的符号优先级 >= 扫描到的优先级,把栈中的符号 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
}