简单计算器实现(C++)
来源:互联网 发布:阳光姐姐嘉年华淘宝网 编辑:程序博客网 时间:2024/06/02 14:30
本人写了一个简单的计算器实现代码,能实现+-*/及()功能.特此备案.
一、开发环境:
Linux操作系统(Fedora虚拟机), vim、g++等开发环境。
二、核心算法
1、 int Test(string str): 对输入的const string类型字符串(计算式)进行检测,发现其是否为一正确的计算表达式,如果是则return 1,如果否则return 0。如“12+23”为正确则返回1,“12*&45”为错误计算式,则返回0。
2、 string stringtoarr(const stringstr):对输入的无括号的conststring类型字符串str进行单元转换,将最终返回其值,如果某个单元“12+23*2”,则将之返回为“58”。
3、 string trims(const string&sub):将输入的带括号的字符串进行去括号操作,最后返回无括号的表达式(对带括号的子字符串部分进行stringtoarr处理,去除括号)。这是一个递归函数,如果子字符串中含有多个括号,则反复地自递归调用。
三、编译与链接
在虚拟机环境下,使用vim环境指令创建Calculation.cpp文件,并用g++进行编译与链接g++ Calculation.cpp –oCal.out。并使程序能正常进行实现计算器功能。
四、自测试报告。
1、对生成的Cal.out文件进行运行,并进行测试用例自测试过程(正异常用例共7组):
正常用例测试:
第一组(加减):12.2+23.0 24+34.6+34+7854.3 56-23.3+23.5-0.12
第二组(乘除):17/56 23*45.75 12.04/34 23.77/34.901*23.0 23.04*0/34.2
第三组(+-*/混合):23.4*23.5/34 23+234*34.3/45.9-23/23.04
第四组(+-*/混合,带一个或多个括号):
(12-45.4)/23.78 (12*23.5-23/(25.7-34.6))*12 2*(12-(45.5*(12.3*(11.92-6))-12.4)*2.3)
错误用例测试:
第一组(字符错误):12<23.2-34.6 89.6/56,2+2 23%7 21^2 2a.0-12 12”3-12
第二组(被除数为零): 12/0.0+12
第三组(式中括号有误): 12-(12.7*(35-45.8)+2 12-(12.7*)35-45.8)+2 12*)34-98(-23
2、部分测试报告截图如下:
*说明:此计算器代码相对较简单,是以一个.cpp文件将三个子函数全部写下。如果在建立的工程需要将子函数写成不成同的.cpp文件,则需要用到Makefile,规定每个程序源文件的编译顺序,否则改动程序时会经历循环反复的编辑à编译à测试过程,比较费时。
五、审评意见:
使用递归算法实现计算器功能,代码相对简洁,但编码不太规范,希望在以后的编码工作中加强规范编码的训练。
附录代码:
//Calculation.cpp : 定义控制台应用程序的入口点。////#include"stdafx.h"#include<stdio.h>#include<iostream>#include<string>#include<stdlib.h>#include<fstream>usingnamespace std; intTest(string as){ string::size_type len=as.size(); string::size_type i=0; int k=0; while(i<len) { if(!((as[i]>='0' &&as[i]<='9') || as[i]=='+' || as[i]=='-' || as[i]=='*' || as[i]=='/'||as[i]=='.' || as[i]=='(' || as[i]==')')) { cout<<"输入的表达式错误,请重新输入!"<<endl; return 0; } if(as[i]=='/'&&as[i+1]=='0') { cout<<"分母不能为零!"<<endl; return 0; } if(as[i]=='(') k++; else if(as[i]==')') { k--; if(k<0) return 0; } i++; } if(k!=0) { cout<<"括号输入错误!"<<endl; return 0; } return 1;} stringstringtoarr(const string str) //将一个字符串转化成两个数组,一个为数字数组保存数字,另一个为字符数组,保存符号{ //此函数将用于无括号的计算。 int i=0,z=0,s,temp; float rate=10.0,itemp=0.0; float valueStr=0.0; float a[40]; char b[20]; for(i=0;i<40;i++) a[i]=0.0; //对数组a[20]初始化 for(i=0;i<20;i++) b[i]=' '; //对数组b[10]初始化 i=0; //把0赋给i for(i=0;i<str[i];i++) { if(str[i]>='0'&& str[i]<='9') //如果字符串str.GetAt(i)的内容是整数 { if(rate==10.0) //整数部分 itemp=itemp*rate+(str[i]-'0'); //获得整数 else //小数部分 { itemp=itemp+rate*(str[i]-'0'); //获得小数 rate=rate/10; //每次让rate小10倍 } } elseif(str[i]=='.') //如果str.GetAt(i)是小数点 rate=0.1; //让rate=0.1,开始计算小数部分 elseif(str[i]=='+') //如果str.GetAt(i)是加号 { a[z]=itemp;itemp=0; //把itemp的值放入双精度数组a中,并把itemp的值改为0 z++; //让z自加一次 b[z]='+'; //把加号放入字符数组b中 z++; //让z自加一次 rate=10.0; //把10赋给rate,确保读取下个数字时,先计算整数部分 } else if(str[i]=='-') //如果str.GetAt(i)是减号 { a[z]=itemp;itemp=0; //把itemp的值放入双精度数组a中,并把itemp的值改为0 z++; //让z自加一次 b[z]='-'; //把减号放入字符数组b中 z++; //让z自加一次 rate=10.0; //把10赋给rate,确保读取下个数字时,先计算整数部分 } else if(str[i]=='*') //如果str.GetAt(i)是乘号 { a[z]=itemp;itemp=0; //把itemp的值放入双精度数组a中,并把itemp的值改为0 z++; //让z自加一次 b[z]='*'; //把减号放入字符数组b中 z++; //让z自加一次 rate=10.0; //把10赋给rate,确保读取下个数字时,先计算整数部分 } else if(str[i]=='/') //如果str.GetAt(i)是除号 { a[z]=itemp;itemp=0; //把itemp的值放入双精度数组a中,并把itemp的值改为0 z++; //让z自加一次 b[z]='/'; //把除号放入字符数组b中 z++; //让z自加一次 rate=10.0; //把10赋给rate,确保读取下个数字时,先计算整数部分 } } a[z]=itemp; //把最后一个整数itemp的值放入双精度数组a中 s=z; //把z的值赋给变量s,用来控制计算结果的循环中的条件,s即为数与值的大小。 for(i=0;i<=s;i++) { if(b[i]=='/') //当循环遇到除号时 { a[i+1]=1/a[i+1]; //把a[i+1]的值改为1/a[i+1] b[i]='*'; //把b[i]的值改为乘号 } } for(i=0;i<=s;i++) { while(b[i]=='*') //当循环遇到乘号时 { a[i-1]=a[i-1]*a[i+1]; for(temp=i+1;temp+2<40;temp++) a[temp]=a[temp+2]; for(temp=i;temp+2<20;temp++) b[temp]=b[temp+2]; } } valueStr=a[0]; for(i=0;i<s;i++) { if(b[i]=='+') valueStr+=a[i+1]; else if(b[i]=='-') valueStr-=a[i+1]; } char svalue[16]; sprintf(svalue,"%f" , valueStr); string ssavalue(svalue); return ssavalue;} stringtrims(const string &sub){ string s1,s2,s3,sp,ss; int i; int counter=0; int left,right; if(string::size_typepos1=sub.find(")")==string::npos) return sub; for(i=0;sub[i];i++) if(sub[i]=='(') { left=i; counter++; break; } for(i=left+1;sub[i];i++) { if(sub[i]=='(') counter++; else if(sub[i]==')') counter--; if(counter==0) { right=i; break; } } s1=sub.substr(0,left); sp=sub.substr(left+1,right-left-1); s2=stringtoarr(trims(sub.substr(left+1,right-left-1))); s3=trims(sub.substr(right+1)); ss=s1+s2+s3; return ss;} voidcalcation(string &str1){ int stTe; if((stTe=Test(str1))<=0) { cout<<"输入字符串有误,请重新输入!!!"<<endl; return; } string sk=trims(str1); string ssk=stringtoarr(sk); cout<<ssk<<endl; cout<<"--------------------"<<endl; } intmain(){ string input_str; int p=1; int tsTest; //string tss; while(1) { cout<<"请输入表达式(退出请输入小写exit):"<<endl; cin>>input_str; cout<<endl; if(input_str.compare("exit")==0) break; if((tsTest=Test(input_str))==1) { calcation(input_str); //tss=trims(input_str); //cout<<stringtoarr(tss)<<endl; } }cout<<"Close this calculation!"<<endl;return 0;}
- 简单计算器实现(C++)
- ANTLR实现简单计算器[C#]
- 《简单计算器实现(c#)》
- c/c++实现简单计算器
- C语言实现一个简单的计算器
- C语言 实现四则运算简单计算器
- GTK实现简单计算器(calculator.c)
- c-简单的计算器
- 计算器功能简单实现
- js简单实现计算器
- PHP实现简单计算器
- 简单的计算器实现
- 【简单计算器】实现加减乘除
- JSP实现简单计算器
- 简单计算器的实现
- 计算器简单实现
- 简单计算器的实现
- Java实现简单计算器
- eclipse开发插件
- OpenCV中特征点提取和匹配的通用方法
- 几种设置表单元素中文本输入框不可编辑的方法
- jQuery判断单选框是否被选中
- 让输入框默认时间为今天
- 简单计算器实现(C++)
- 获取结构体中的字段偏移量或结构体地址
- 时间大小比较
- 为什么jdk中把String类设计成final?
- 69
- 图片上传大致思路
- UVa 612 - DNA Sorting
- Ubuntu 10.04 下安装codeblock
- suse linux原创案例02: 系统下英文环境下显示中文内容