计算器(只能针对整形),支持+-*/(),不支持负数

来源:互联网 发布:股票场外期权知乎 编辑:程序博客网 时间:2024/06/16 05:47

一个计算式,比如 30 + 7 *4 - (5 + 69) /3

利用计算机计算,就需要将其化成逆波兰式。 化成逆波兰式的结果为 30  7  4  *  +  5  69  +   3  /  -

这样子就可以直接计算了:遇到操作符,就从栈中弹出两个数字,计算完在push到里面

过程: 30  28(遇到*) +  5  69  +  3  /  -

              58(遇到+) 5  69  + 3  /  -

              58  74(遇到+) 3  /  -

              58  24(遇到/) -

              34  为最终结果

 

我的代码实现过程是:

开辟两个栈,一个栈用来存放数值,另一个栈用来存放操作符。

numS

opS

 

过程如下:

(1)

numS: 30  7

opS:  +

(2)

下面即将读到 *, 发现*的优先级 比opS栈顶的优先级高,所以入栈,结果为:

numS: 30  7

opS:  + *

(3)

numS: 30  7 4

opS:  + *

(4)下面读到的是 ‘-’, 比top(opS)优先级低, 所以从 opS中弹出栈顶 *,从numS中弹出两个数 4 ,7 ,计算后再把结果push到 numS

numS: 30  28

opS: +

此时 ‘-’ 优先级依然不高于top(opS),所以 继续弹出两个数与一个操作符,再把运算结果push到栈中。一直如此,知道操作符栈为空,或者top(opS)优先级高于‘-’;

最后把‘-’压入栈。

numS: 58

opS: - 

(5)

numS:  58  5  69

opS: - ( +         //(的优先级设为最低)

(6)

下面就要读到‘)’。 一直弹出两个数与一个运算符,知道遇到‘(’

numS:  58  74

opS:  -

(7)

numS: 58 74 3

opS: - /

(8)整个序列都读完之后,若 操作符栈不为空,则逐个弹出。

numS:58   24

opS:  -

最后一步得到结果34!!!

 

参考代码: (栈的定义 见我的文章 栈ADT 中)

#include<stdio.h>
#include<stdlib.h>
#include<memory.h>
#include<ctype.h>

int calculate(const char *p)
{
 int num;
 int result;
 char op,t;
 int i=0;
 stack *opS =createStack(100);
 stack *numS =createStack(100);
 while(*p != '\0')
 {
  t=*p;
  if(isspace(t))
  {
   p++;
   continue;
  }
  else if( isdigit(t) )
  {
   /*处理一个数字*/
   num = 0;
   while( isdigit(*p) )
   {
    num =10*num+(*p-'0');
    p++;
   }
   push(num,numS);  //获得一个数字,并把这个数字压栈
  }
  else if( t=='+' || t=='-' ||t=='*' || t=='/'|| t =='(' || t==')')
  {
   if(isEmpty(opS) || t=='(')
   {
    push(t,opS);
    p++;
   }
   else if (t ==')')
   {
    int num1,num2,op;

    op=pop(opS);
    while(op != '(')
    {
     num1 = pop(numS);
     num2 = pop(numS);
     switch(op)
     {
     case '+':
      result=num2+num1;
      break;
     case '-':
      result=num2-num1;
      break;
     case '*':
      result=num2*num1;
      break;
     case '/':
      result =num2/num1;
      break;
     }
     push(result,numS);
     op=pop(opS);
    }
    p++;
   }
   else
   {
    op = top(opS);
    while(getPrio(t) <=getPrio(op) )
    {
     int num1,num2;
     num1 = pop(numS);
     num2 = pop(numS);
        op=pop(opS);
     switch(op)
     {
     case '+':
      result=num2+num1;
      break;
     case '-':
      result=num2-num1;
      break;
     case '*':
      result=num2*num1;
      break;
     case '/':
      result =num2/num1;
      break;
     }
     push(result,numS);
     
     if(isEmpty(opS))
      break;
     op = top(opS);
    }
    push(t,opS);
    p++;
   }
  }
 }

 while(!isEmpty(opS))
 {

  int num1 = pop(numS);
  int num2 = pop(numS);
  int op = pop(opS);
  switch(op)
  {
  case '+':
   result=num2+num1;
   break;
  case '-':
   result=num2-num1;
   break;
  case '*':
   result=num2*num1;
   break;
  case '/':
   result =num2/num1;
   break;
  }
  push(result,numS);
 }
 return top(numS);
}

int main()
{
 int num= calculate("30+7  *4 -(5 +69 )/ (3-1) ");
 printf("%d\n",num);
 printf("%d\n",30+7  *4 -(5 +69) /(3-1) );
 return 0;
}