小程序(十六)简单四则运算
来源:互联网 发布: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”
输入一个只包含个位数字的简单四则运算表达式字符串,计算该表达式的值
注:
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; }
- 小程序(十六)简单四则运算
- 四则运算(带括号)的小程序
- 四则运算小程序
- 自己写得C++简单的四则运算小程序
- winform程序之comboBox控件应用四则运算(简单)
- 一个计算复数四则运算的小程序
- java中复数四则运算的小程序
- 每天一个C++小程序(十六)--线性表
- 简单四则运算算法(一)
- 简单四则运算算法(二)
- 程序人生(十六)
- 简单四则运算
- 简单四则运算
- 简单四则运算
- 简单四则运算
- 简单四则运算
- 简单四则运算
- 简单四则运算
- hdu 2089 不要62(数位dp)
- 更新整理本人所有博文中提供的代码与工具(Java,2013.08)
- 函数可重入和可重载
- Codeforces Yandex.Algorithm 2011 Qualification 2 / 82A Double Cola (数学规律&模拟)
- C++关闭所有窗口
- 小程序(十六)简单四则运算
- 《C++ Primer Plus》读书笔记----CHAP1
- 网络请求
- matlab cannot save changes to the path
- <设计模式沉思录>读后感2
- 黑马程序员之了解java
- 大数据下的数据分析-Hadoop架构解析(1)
- DateDiff函数解析
- 更新整理本人所有博文中提供的代码与工具(Java,2013.08)