数据结构_calculator

问题描述

V 发明了一个神奇的整数计算器:
给定一个合法的表达式,这个计算器能求出这个表达式的最终答案。
表达式可能包含:
+:运算符,整数加法。如 1+1=2
-:运算符,整数减法。如 1-1=0
*:运算符,整数乘法。如 1*1=1
/:运算符,整数除法。如 3/2=1
(:左括号
):右括号
操作数:保证为非负整数,且操作数没有正号(如不会出现+1 等)
现在,给定一个表达式,小 V 在用这个计算器计算前想先知道最终答案是多少,你能
帮帮他吗?


数据输入
一个合法的表达式,表达式长度不超过 1000


数据输出
表达式的最终结果。


★Notice
题目保证:输入的操作数,计算的中间值,计算的最终结果都在 int 范围内


样例

1+1    2

1+2/3   1

(1+2)*3   9

 

解题思路

  solve1

    建立两个栈:数字栈、符号栈

    按顺序遍历算式

    遇到数字注意按多位数读取,压入数字栈

    若符号栈为空或为 ' ( ' ,压入符号栈

    遇到 + - / *,向前计算优先级大于等于本符号优先级的,算到 ' ( '停止。将本符号压入符号栈

    优先级 / * 最高,+ - 次之

    故 + - 前面的 + - * / 都要算, * / 前面的* / 要算, + -不算,遇到 + - 停止

    遇到 ' ) ',向前算到 ' ( '

    最后数字栈栈顶元素即为解

  solve 2

    将原表达式转换为后续表达式。

    为能正确读取后续表达式,可在所有数字、符号间加上空格。

    此时,表达式将比原表达式长,原来长度1000数组不够用,要开大一点

    最后用后续表达式计算结果

  附:中缀表达式转后缀表达式的方法

    1.遇到操作数:直接输出(添加到后缀表达式中)
    2.栈为空时,遇到运算符,直接入栈
    3.遇到左括号:将其入栈
    4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。
    5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈
    6.最终将栈中的元素依次出栈,输出。

code

  1 #include <stdio.h>
  2 #include <iostream>
  3 using namespace std;
  4 #include <stack>
  5 #include <string.h>
  6 
  7 inline bool isNum(char c)
  8 {
  9     return c>='0' && c<='9';
 10 }
 11 
 12 inline int toInt(char c)
 13 {
 14     return c-'0';
 15 }
 16 
 17 int calc(int nl,int nr,char s)
 18 {
 19     if(s=='+')         return nl+nr;
 20     else if(s=='-')    return nl-nr;
 21     else if(s=='*')    return nl*nr;
 22     else if(s=='/')    return nl/nr;
 23     printf("errror");
 24     return 0;
 25 }
 26 
 27 int main()
 28 {
 29     int i,j,k;
 30     char str[1024]={0};
 31     int len;
 32     scanf("%s",str);
 33     len = strlen(str);
 34     
 35     stack<int> num;
 36     stack<int> signal;
 37     
 38     for(i=0;i<len;i++)
 39     {
 40         if(isNum(str[i]))
 41         {
 42             int n = toInt(str[i]);
 43             for (j = i + 1; j < len && isNum(str[j]); j++)
 44                 n = n * 10 + toInt(str[j]);
 45             num.push(n);
 46             i = j - 1;
 47         }
 48         else // is signal
 49         {
 50             char thissign = str[i];
 51             if(thissign=='(' || signal.empty())
 52             {
 53                 signal.push(thissign);
 54             }
 55             else if(thissign=='+' || thissign=='-')
 56             {
 57                 while(!signal.empty() && signal.top()!='(')
 58                 {
 59                     int nr = num.top();
 60                     num.pop();
 61                     int nl = num.top();
 62                     num.pop();
 63                     num.push(calc(nl,nr,signal.top()));
 64                     signal.pop();
 65                 }
 66                 signal.push(thissign);
 67             }
 68             else if(thissign=='*' || thissign=='/')
 69             {
 70                 while(!signal.empty() && ( signal.top()=='*' || signal.top()=='/') )
 71                 {
 72                     int nr = num.top();
 73                     num.pop();
 74                     int nl = num.top();
 75                     num.pop();
 76                     num.push(calc(nl,nr,signal.top()));
 77                     signal.pop();
 78                 }
 79                 signal.push(thissign);
 80             }
 81             else if(thissign==')')
 82             {
 83                 while(!signal.empty() && signal.top()!='(')
 84                 {
 85                     int nr = num.top();
 86                     num.pop();
 87                     int nl = num.top();
 88                     num.pop();
 89                     num.push(calc(nl,nr,signal.top()));
 90                     signal.pop();
 91                 }
 92                 signal.pop();
 93             }
 94         }
 95     }
 96     while(!signal.empty())
 97     {
 98         int nr = num.top();
 99         num.pop();
100         int nl = num.top();
101         num.pop();
102         num.push(calc(nl,nr,signal.top()));
103         signal.pop();
104     }    
105     printf("%d\n",num.top());
106     return 0;
107 }
108         

 

posted @ 2017-10-12 14:33  cbattle  阅读(310)  评论(0编辑  收藏  举报