编程题:四则运算

题目描述

请实现如下接口

    /* 功能:四则运算

     * 输入:strExpression:字符串格式的算术表达式,如: "3+2*{1+2*[-4/(8-6)+7]}"

         * 返回:算术表达式的计算结果

     */

    public static int calculate(String strExpression)

    {

        /* 请实现*/

        return 0;

    } 

约束:

  1. pucExpression字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。

  2. pucExpression算术表达式的有效性由调用者保证; 

 

输入描述:

输入一个算术表达式

输出描述:

得到计算结果

输入例子:
3+2*{1+2*[-4/(8-6)+7]}
输出例子:
25
思路:中缀转后缀;负数添0;

#include <iostream>

#include <string>
#include <vector>
#include <stack>
using namespace std;
int is_parenthese(char c)   //判断是否为小括号
{
if (c == '(' || c == ')'){
return 1;
}
else return 0;
}
int perior(char c)   //判断并返回操作符的优先级
{
if (c == '(' || c == ')') return 1;
else if (c == '+' || c == '-') return 2;
else  return 3;   //if (c == '*' || c == '/')
}
void check(char c, stack <char> &cnt2, deque <char> &cnt3)   //判断操作符的优先级
{
if (cnt2.empty()){   //cnt2当前为空时,直接将c入栈
cnt2.push(c);
return;
}
if (is_parenthese(c)){    //如果操作符为小括号
if (c == '('){    //当输入左括号的时候
cnt2.push(c);
}
else{    //当输入为右括号的时候
while (cnt2.top() != '('){   //依次输出,直到左括号直接删除
char tmp = cnt2.top();
cnt3.push_back(tmp);
cnt2.pop();
}
cnt2.pop();
}
}
else{   //不是括号的情况,加减与乘除
   char tmp = cnt2.top();   //取出当前栈顶的位置
if (perior(c) <= perior(tmp)){   //当前操作符的优先级低于cnt2中顶部的优先级时
    cnt3.push_back(tmp);  //将cnt2顶部的操作符入cnt3;
  cnt2.pop();
  check(c, cnt2, cnt3);   //循环当前输入c与更新后的cnt2的比较
      }
else{
   cnt2.push(c);   //当c比当前栈顶操作符优先级大,将c入cnt2栈中
}    
}
}
void Allocate(deque <char> &cnt1, stack <char> &cnt2, deque <char> &cnt3) //将中缀转后缀
{
while (!cnt1.empty()){
char c = cnt1.front();
cnt1.pop_front();
if (c >= '0' && c <= '9'){
cnt3.push_back(c);
}
else{
check(c, cnt2, cnt3);
}
}
while (!cnt2.empty()){    //输入结束后,将cnt2中剩余的操作符全部弹出
char tmp = cnt2.top();
cnt3.push_back(tmp);
cnt2.pop();
}
}
void Calculate(deque <char> &cnt3, stack <int> &cnt4)
{
while (!cnt3.empty())
{
char c = cnt3.front();
cnt3.pop_front();
if (c >= '0'&& c <= '9'){   //说明是操作数
int op = c - '0';   //将ASCALL码转化成真实的数值
cnt4.push(op);
}
else{    //当为操作符时
int op1 = cnt4.top();
cnt4.pop();
int op2 = cnt4.top();
cnt4.pop();
switch (c)
{
case '+': cnt4.push(op2 + op1);
break;
case '-': cnt4.push(op2 - op1);
break;
case '*': cnt4.push(op2 * op1);
break;
case '/': cnt4.push(op2 / op1);
break;
}
}
}
}
int main()
{
string str;
cout << "请输入要计算的算式:" << endl;
cin >> str;
deque <char> cnt1;   //存放中缀(计算的算式) deque的好处是可以从前从后进行操作
stack <char> cnt2;   //存放操作符
deque <char> cnt3;   //存放后缀
stack <int> cnt4;   //存放后缀计算辅助 注意:类型的变化
for (int i = 0; i < str.size(); i++)
{
//将所有大括号和中括号均转化为小括号,简化判断流程
if (str[i] == '[' || str[i] == '{') {   
str[i] = '(';
}
if (str[i] == ']' || str[i] == '}') {
str[i] = ')';
}
//cnt1.push_back(str[i]);
}
//将所有负数前面补0,以便后续计算
for (int i = 1; i < str.size(); i++){
if (str[0] == '-'){
str.insert(0, "0");
}
if (str[i] == '-' && str[i - 1] == '('){
str.insert(i, "0");
}
}
for (int i = 0; i < str.size(); i++){ //将计算的算式放入cnt1栈中
cnt1.push_back(str[i]);
}
Allocate(cnt1, cnt2, cnt3);   //中缀转后缀
cout << "check后缀的输出结果是否正确:" << endl;
for (int j = 0; j < cnt3.size(); j++){
cout << cnt3[j] << " ";
}
cout << endl;
Calculate(cnt3, cnt4);
cout << "计算结果为:" << endl;
cout << cnt4.top() << endl;
return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值