小程序(十六)简单四则运算

来源:互联网 发布:java adt是什么 编辑:程序博客网 时间:2024/05/20 16:12
问题描述:
输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值
注:
3.1、表达式只含 +, -, *, / 四则运算符,不含括号
3.2、表达式数值只包含个位整数(0-9),且不会出现0作为除数的情况
3.3、要考虑加减乘除按通常四则运算规定的计算优先级
3.4、除法用整数除法,即仅保留除法运算结果的整数部分。比如8/3=2。输入表达式保证无0作为除数情况发生
3.5、输入字符串一定是符合题意合法的表达式,其中只包括数字字符和四则运算符字符,除此之外不含其它任何字符,不会出现计算溢出情况
要求实现函数:
int calculate(int len,char *expStr)
【输入】 int len: 字符串长度;char *expStr: 表达式字符串;
【输出】 无
【返回】 计算结果
示例:
1)输入:char *expStr = “1+4*5-8/3”
函数返回:19
2)输入:char *expStr = “8/3*3”

函数返回:6


第一种方法:利用后缀表达式:

#include<stdio.h>#include<stdlib.h>#include<stack>using namespace std;int calculate(int len,char *expStr){  int i;  int j=0;  char * postfix = (char*)malloc(sizeof(char)*len);  stack<char> oper;  for(i=0;i<len;i++)//计算后缀表达式  {if(expStr[i]>='0' && expStr[i]<='9')   postfix[j++] = expStr[i];elseswitch(expStr[i]){  case'+':  case'-':if(oper.empty())  { oper.push(expStr[i]);    break;  }  while(!oper.empty() && oper.top()!='(')  {//如果是'+'或'-',就把栈顶及以以下的元素全部出栈到后缀表达式中,                   //(按照当前元素优先级小于或等于栈顶元素,则将栈顶元素出栈的原则,   //如果栈顶元素是'(',则认为 '(' 优先级最小。因此将'+'或'-'压栈。  postfix[j++] = oper.top();  oper.pop();   }       oper.push(expStr[i]);   break;          case'*':  case'/':if(oper.empty())  {    oper.push(expStr[i]);break;  }      if(oper.top()!='*'&&oper.top()!='/')      oper.push(expStr[i]);  else     {  while(!oper.empty() && (oper.top()=='*' || oper.top()=='/'))  {      postfix[j++] = oper.top();      oper.pop();  }  oper.push(expStr[i]);    }  break;  case'(':oper.push(expStr[i]);break;//左括号在进栈前,认为优先级是最大的  case')':while(oper.top()!='(')  {//当前元素是右括号时,认为右括号的优先级最小,将栈中元素都出栈到   //后缀表达式中,直到遇到左括号,这时直接将左括号弹出(删除),而   //且右括号也不入栈(后缀表达式中是没有括号的)     postfix[j++] = oper.top(); oper.pop();    }  oper.pop();  break;  default:exit(0);     }  }  while(!oper.empty())  {  postfix[j++] = oper.top();  oper.pop();  }  postfix[j]='\0';  //printf("%s\n",postfix);  //利用后缀表达式求值  //每当遇到一个操作符是,就将它的前两个数弹出  //计算相应的值以后,再把结果入栈  int postfix_len = strlen(postfix);  stack<int> pos_str;  int t1,t2,t;  for(i=0;i<postfix_len;i++)  {  if(postfix[i]!='+'&&postfix[i]!='-'&&postfix[i]!='*'&&postfix[i]!='/')  pos_str.push(postfix[i]-'0');  else  {      t1 = pos_str.top(); pos_str.pop();    t2 = pos_str.top(); pos_str.pop();        switch(postfix[i]){   case'+': t = t1+t2;break;   case'-': t = t2-t1;break;//因为先弹出来的t1是减数,t2是被减数   case'*': t = t1*t2;break;   case'/': t = t2/t1;break;//因为先弹出来的t1是除数,然后t2是被除数   default: exit(0);}pos_str.push(t);   }   }   int result = pos_str.top();   return result;}int main(){ char *str="5-(4+5)*2*7/4-5/(3+1)"; int len = strlen(str); int relVal=calculate(len,str); printf("%d\n",relVal); system("pause"); return 0;}


第二种方法:利用栈和优先级来算,不过这种方法中间计算的结果也不能大于10,并且不能加括号

#include<stdlib.h>#include<stdio.h>#include<iostream>#include<stack>using namespace std;stack<char> OPTR;//运算符stack<int>  OPND;//运算数int In(char c){  //判断是否为运算符  switch(c)  {  case '+':  case '-':  case '*':  case '/':  case '#': return 1;  default:  return 0;   }}char Precede(char t1,char t2) //t1是栈顶元素,t2是原运算式的字符{    if(t1=='#' && t2=='#')       return '=';    if(t1=='#')       return '<';    if(t2=='#')       return '>';    if(t1=='+' || t1=='-')    {       if(t2=='+' || t2=='-')           return '>';       else           return '<';    }    if(t1=='*' || t1=='/')       return '>';}char Operate(char a,char theta,char b){char c;//a = double(a);//b = double(b);a = a-48;b = b-48;//int e,f;//e = a - '0';//f = b - '0';switch(theta){case '+': c = a+b+48;          break;case '-': c = a-b+48;          break;case '*': c = a*b+48;          break;case '/': c = a/b+48;          break;     }//c = char(c);return c;}int calcucate(int len, char *expStr){   //char *expStr1 = expStr;//strcat(expStr1,"#");int i=0;char c,theta,a,b;OPTR.push('#');c = expStr[i];       char x = OPTR.top();while(c!='#' || x!='#'){c = expStr[i];     if(In(c))//是加减乘除运算符之一switch(Precede(x,c)){  case '<':OPTR.push(c);//栈顶元素优先级低        i++;   break;  case '=':i++;       break;  case '>':theta = OPTR.top();       OPTR.pop();       b = OPND.top();   OPND.pop();   a = OPND.top();   OPND.pop();   OPND.push(Operate(a,theta,b));     }else if(c>='0' && c<='9'){OPND.push(c);i++;}else //c是非法字符        {printf("ERROR\n");    exit(0);}x = OPTR.top();//OPTR.pop(); }x = OPND.top();return x;}int main(){ printf("请输入运算式,中间值在0到9之间\n"); //char *expStr = "4+2*1-3+5#"; char *expStr = "1-3+2*1+4*1-1-1#"; int len = strlen(expStr); int result = calcucate(len , expStr); printf("%c\n",result); system("pause"); return 0;}

第三种方法:用数组模拟栈的实现,不带括号

#include<stdio.h>#include<stdlib.h>#include<string.h>int calculate(int len,char *expStr){int* data = (int*)malloc(sizeof(int)*len);     char* oper = (char*)malloc(sizeof(char)*len);    int datatop = -1;int opertop = -1;    int num=0;int num1=0;int num2=0;memset(data,0,sizeof(int)*len);memset(oper,0,sizeof(char)*len);    for(int i=0;i<len;i++){   if( expStr[i]>='0' && expStr[i]<='9')//如果是数字,就将它压入data栈    data[++datatop] = expStr[i]-'0';   if(expStr[i]=='+' || expStr[i]=='-')//如果是字符,'+','-',就将它压入oper栈       oper[++opertop] = expStr[i];      if(expStr[i]=='*')//如果是乘号,就把乘号左右两边的数字相乘,将得到的结果放入data中。   {                num1 = data[datatop];num2 = expStr[++i]-'0';num = num1*num2;    data[datatop] = num;   }      if(expStr[i]=='/')   {num1 = data[datatop];num2 = expStr[++i]-'0';num = num1/num2;    data[datatop] = num;   }   }    char oper_now;//计算只有加减的运算    int flag = datatop;int data_num = 0,oper_num = 0;while(data_num<flag){num1 = data[data_num++];num2 = data[data_num];oper_now = oper[oper_num++];if(oper_now=='+'){num = num1+num2;data[data_num] = num;}if(oper_now=='-'){num = num1-num2;data[data_num] = num;}}     return data[data_num];}   int main(){ char * str = "2-3-5+4*3-2"; int len = strlen(str); int result=calculate(len,str); printf("%d\n",result); return 0;}


以上都是操作数是个位数,如果操作数大于1位,那么我们可以用以下方法来将多个字符转化为数字:


int leftNum = convertToDigit(pInputStr)

<p>int convertToDigit(const char *&str)//将从str开始的数字即其后的数字转换为int,最终str指向下一个运算符或'\0'.</p><p>{</p><p>    int result = 0;</p>
     while (isdigit(*str))    {        result = result * 10 + (*str - '0');        str++;    }     return result;}


操作数大于1位的四则运算的代码:

#include<stdio.h>  #include<stdlib.h>  #include<string.h>  #include<math.h>#include<ctype.h> int covertodigit(char *s,int &num){  int m=0;  while( isdigit(*s) )  { m = m*10+(*s-'0');     s++; num++;  }  return m;}int calculate(int len,char *expStr) {  int *data = (int *)malloc(sizeof(int)*len);  char *oper = (char *)malloc(sizeof(char)*len);  int datatop = -1;  int opertop = -1;  int sum = 0;  int m = 0;  int num = 0;  for(int i=0;i<len;i++)  {  if(isdigit(expStr[i]))  {  m = covertodigit(expStr+i,num);  i = i+ num-1 ;      data[++datatop] = m;      num = 0;  }  else  {   if(expStr[i]=='+' || expStr[i] =='-')  oper[++opertop] = expStr[i];   else   {    if(expStr[i]=='*')data[datatop] = data[datatop] * (expStr[++i]-'0');        if(expStr[i]=='/')    data[datatop] = data[datatop] / (expStr[++i]-'0');   }  }  }  sum = data[0];  int k=0;  for(int j=1;j<=datatop;j++)  {    if(oper[k]=='+')       sum = sum + data[j];    if(oper[k]=='-')   sum = sum - data[j];k++;  }  return sum;}int main()  {   char * str = "20-3-5+4*3-2";   int len = strlen(str);   int result=calculate(len,str);   printf("%d\n",result);   return 0;  } 


原创粉丝点击