四则运算

输入描述:

输入一个算术表达式

输出描述:

得到计算结果

 

示例1

输入

3+2*{1+2*[-4/(8-6)+7]}

输出

25

1.运算符的优先级:

    在运算过程中,任意两个前后相继出现的运算符 \Theta _{1}, \Theta_{2}的优先关系如下表所示:

运算符之间的优先关系
 +-*/()[]{}@
+>><<<><><>>
->><<<><><>>
*>>>><><><>>
/>>>><><><>>
(<<<<<= > > 
)>>>> >>> >>
[<<<<<<<= > 
]>>>>   > >>
{<<<<<<<<<= 
}>>>>     >>
@<<<<< < < =

2.算法基本过程如下:

    首先初始化操作数栈Operand和运算符栈Operator,并将表达式起始符"@"压入运算符栈。加入"@"是为了方便计算,例如:

@(7+15)*(23-28/4)@。

    再依次读入表达式中的每个字符,若是操作数,则直接进入操作数栈Operand;若是运算符,则与运算符栈Operator的栈顶运算符进行优先权比较,并作如下处理:

(1).若栈顶运算符的优先级低于刚读入的运算符,则让刚读入的运算符进Operator栈。

(2).若栈顶运算符的优先级高于刚读入的运算符,则让栈顶运算符退栈,送入op,同时将操作数栈Operand连退两次,得到两个操作数a,b,对a,b进行op运算后,将运算结果作为中间结果压入Operand栈。

(3).若栈顶运算符的优先级与刚读入的运算符的运算符的优先级相同,说明左右括号相遇,只需要将栈顶运算符(左括号)退栈即可。

3.本题注意负号的处理,负号又能是负数的前缀标志,也有可能是减法运算符。

#include <stdio.h>
#include <string.h>
char table[11][11] = { 
	{'>', '>', '<', '<', '<', '>', '<', '>', '<', '>', '>'},
	{'>', '>', '<', '<', '<', '>', '<', '>', '<', '>', '>'},
	{'>', '>', '>', '>', '<', '>', '<', '>', '<', '>', '>'},
	{'>', '>', '>', '>', '<', '>', '<', '>', '<', '>', '>'},
	{'<', '<', '<', '<', '<', '=', '#', '>', '#', '>', '#'},
	{'>', '>', '>', '>', '#', '>', '>', '>', '#', '>', '>'},
	{'<', '<', '<', '<', '<', '<', '<', '=', '#', '>', '#'},
	{'>', '>', '>', '>', '#', '#', '#', '>', '#', '>', '>'},
	{'<', '<', '<', '<', '<', '<', '<', '<', '<', '=', '#'},
	{'>', '>', '>', '>', '#', '#', '#', '#', '#', '>', '>'},
	{'<', '<', '<', '<', '<', '#', '<', '#', '<', '#', '='}
};
char opp[11] = {'+','-','*','/','(',')','[', ']', '{' , '}','@'}; 
int Execute(int a, char op, int b) {
    switch(op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
    }
}
char Cmp(char a, char b) {
	int row, col;
	for(int i = 0; i < 11; i++) {
		if(a == opp[i])
			row = i;
		if(b == opp[i])
			col = i;
	}
	return table[row][col];
}
int ExpEvaluation(char str[]) {
	char Operator[105]; //操作符栈 
	int Operand[105]; //操作数栈 
    int operandPointer = 0; //操作数栈顶指针 
    int operatorPointer = 0; //操作符栈顶指针 
    int i = 0;
    int n = strlen(str);
    int a, b, val;
    char op;
    int sign = 1;
    Operator[operatorPointer++] = '@';
    while(str[i] != '@' || Operator[operatorPointer - 1] != '@') {
		if((str[i] == '-') && (str[i-1] == '{' || str[i-1] == '[' || str[i-1] == '(' || str[i-1] == '@')) {//负号是负数的标记 
			sign = -1;
			i++;
			continue;
		}
        if(!(str[i] >= '0' && str[i] <= '9')) { //操作符 
        	sign = 1;
            switch(Cmp(Operator[operatorPointer-1], str[i])) {
                case '<': Operator[operatorPointer++] = str[i];
                    i++;
                    break;
                case '=': operatorPointer--;
                    i++;
                    break;
                case '>': a = Operand[--operandPointer];
                    b = Operand[--operandPointer];
                    op = Operator[--operatorPointer];
                    val = Execute(b, op, a);
                    Operand[operandPointer++] = val;
                    break;
        	}
        }
        else { //操作数 
            int temp = 0;
            while(str[i] >= '0' && str[i] <= '9') {
                temp = temp * 10 + str[i] - '0';
                i++;
            }
            Operand[operandPointer++] = temp*sign;
        }
    }
    return Operand[operandPointer-1];
}
int main() {
    char s[105];
    while(gets(s)) {
    	s[strlen(s)] = '@';
        int ans = ExpEvaluation(s);
        printf("%d\n", ans);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值