要求能够处理括号,能够处理2*((1+2)+3+5/2)/2-6这种复杂公式。c语言实现,多谢!
2条回答 默认 最新
- qfl_sdu 2021-07-04 21:36关注
代码如下,如有帮助,请采纳一下,谢谢。
#include <iostream> #include <string> #include <list> using namespace std; //判断是否合法 bool isValid(string &str) { char spec[] = {'+','-','*','/','{','}','[',']','(',')'}; //删除空格 unsigned int i=0,j=0; char buf[100] = {0}; while(i<str.length()) { if(str.at(i)== ' ') { i++; continue; } else { buf[j++] = str.at(i); i++; } } str = buf; unsigned int len = str.length(); if (str.at(len -1) != '=') { cout << "公式需以=结束"<< endl; return false; }else str = str.substr(0,len-1); //判断是否有非数字的内容 i = 0; len = str.length(); while(i < len) { if(str.at(i)< '0' || str.at(i) > '9' ) { for (j =0;j<10;j++) { if(str.at(i) == spec[j]) break; } if(j == 10) { cout << "公式中存在非法字符:" << str.at(i)<< endl; return false; } } i++; } //遇到3(2+3)、(2+3)3这种直接提示错误,不默认插入* i= 0; while(i < str.length()-1) { if(str.at(i) >= '0' && str.at(i) <= '9') { if(str.at(i+1)== '(' || str.at(i+1) == '[' || str.at(i+1) == '{') { cout << "在" << str.at(i) << "和" << str.at(i+1) << "之间需要添加运算符" << endl; return false; } } if(str.at(i)== ')' || str.at(i) == ']' || str.at(i) == '}') { if(str.at(i+1) >= '0' && str.at(i+1) <= '9') { str.insert(i+1,1,'*'); cout << "在" << str.at(i) << "和" << str.at(i+1) << "之间需要添加运算符" << endl; return false; } } i++; } return true; } //判断是否是数字 bool isNmb(string s) { unsigned int i = 0; if(s.empty()) return false; if(s.at(0) == '-') { i=1; while(i<s.length()) { if(s.at(i) == '.') { i++; continue; } if(s.at(i)< '0' || s.at(i) >'9') return false; i++; } }else { i = 0; while(i<s.length()) { if(s.at(i) == '.') { i++; continue; } if(s.at(i)< '0' || s.at(i) >'9') return false; i++; } } return true; } //判断数字是否是整数 bool isZs(string s) { unsigned int i = 0; while(i<s.length()) { if(s.at(i) == '.') return false; i++; } return true; } //处理一个最简单的计算公式--TO BE TEST bool DealSmple(string str,string &out) { unsigned int i =0,j=0; //将字符串分隔 list<string> vp; int prepos =0; while(i<str.length()) { if (str.at(i) == '+' || str.at(i)=='*' || str.at(i) == '/' ) { string tmp = str.substr(prepos,i-prepos); vp.push_back(tmp); vp.push_back(str.substr(i,1)); i++; prepos = i; }else if( str.at(i) =='-') //查找连续--的情况 { if( (i == 0) || (vp.size() > 0 && (vp.back().compare("+") == 0 || vp.back().compare("-") == 0 || vp.back().compare("*") == 0 || vp.back().compare("/") == 0)) ) //如果上一字符是-号,那么把当前的-留给下面的字符 i++; else { string tmp = str.substr(prepos,i-prepos); vp.push_back(tmp); vp.push_back(str.substr(i,1)); i++; prepos = i; } } else i++; } if(prepos == str.length()) { cout << "公式中存在以"<< str.at(str.length()-1) << "结尾的非法公式段"<<endl; return false; } vp.push_back(str.substr(prepos,str.length() - prepos)); //如果只有一个元素,直接退出 if(vp.size() == 1) { out = vp.front(); return true; } //计算乘法除法 list<string>::iterator it = vp.begin(); list<string>::iterator tmp; for (;it != vp.end();) { if(it->compare("*")==0 )//先处理乘法和除法 { if (it == vp.begin()) { cout << "*出现在公式的开头"<< endl; return false; } it++; if (it == vp.end()) { cout << "*出现在公式的末尾" << endl; return false; } string nmb2 = *it; tmp = it; tmp--; vp.erase(it); it = tmp; tmp--; vp.erase(it); it = tmp; string nmb1 = *it; //判断是否是数字 if ((!isNmb(nmb1)) || (!isNmb(nmb2))) { cout << "存在多个连续的运算符或者数字个数不正确" << endl; return false; } char val[20]={0}; //判断两个数是否都是整数 if (isZs(nmb1) && isZs(nmb2)) { int a = atoi(nmb1.c_str()); int b = atoi(nmb2.c_str()); int c = a*b; itoa(c,val,10); }else { double a = atof(nmb1.c_str()); double b = atof(nmb2.c_str()); double c = a*b; gcvt(c,10,val); } it = vp.insert(it,val); it++; vp.erase(it); it = vp.begin(); }else if (it->compare("/") == 0) { if (it == vp.begin()) { cout << "/出现在公式的开头"<< endl; return false; } it++; if (it == vp.end()) { cout << "/出现在公式的末尾" << endl; return false; } string nmb2 = *it; tmp = it; tmp--; vp.erase(it); it = tmp; tmp--; vp.erase(it); it = tmp; string nmb1 = *it; //判断是否是数字 if ((!isNmb(nmb1)) || (!isNmb(nmb2))) { cout << "存在多个连续的运算符或者数字个数不正确" << endl; return false; } char val[20]={0}; //判断两个数是否都是整数 if (isZs(nmb1) && isZs(nmb2)) { int a = atoi(nmb1.c_str()); int b = atoi(nmb2.c_str()); if(b==0) { cout << "除数为0"<< endl; return false; } int c = a/b; itoa(c,val,10); }else { double a = atof(nmb1.c_str()); double b = atof(nmb2.c_str()); if(b==0.0) { cout << "除数为0"<< endl; return false; } double c = a/b; gcvt(c,10,val); } it = vp.insert(it,val); it++; vp.erase(it); it = vp.begin(); }else it++; } //计算加减 bool iszhs = true; for (it=vp.begin();it != vp.end(); it++) { if (!isZs(*it)) { iszhs = false; break; } } if (vp.size() == 1) { out = vp.front(); return true; }else { if (iszhs) { int sum = 0; it = vp.begin(); string tt = *it; sum += atoi(tt.c_str()); it++; while(it != vp.end()) { string ts = *it; it++; if(it == vp.end()) { cout << "公式运算中出现以运算符结尾的情况"<< endl; return false; } string nmb3 = *it; if (ts.compare("+") == 0) { sum += atoi(nmb3.c_str()); }else if (ts.compare("-") == 0) { sum -= atoi(nmb3.c_str()); }else { cout << "公式出现不匹配的运算符" << endl; return false; } it++; } char bufout[20] ={0}; itoa(sum,bufout,10); out = bufout; return true; }else { double sum = 0.0; it = vp.begin(); string tt = *it; sum += atof(tt.c_str()); it++; while(it != vp.end()) { string ts = *it; it++; if(it == vp.end()) { cout << "公式运算中出现以运算符结尾的情况"<< endl; return false; } string nmb3 = *it; if (ts.compare("+") == 0) { sum += atof(nmb3.c_str()); }else if (ts.compare("-") == 0) { sum -= atof(nmb3.c_str()); }else { cout << "公式出现不匹配的运算符" << endl; return false; } it++; } char bufout[20] ={0}; gcvt(sum,10,bufout); out = bufout; return true; } } return true; } //处理括号 bool DealKuhao(string &strSrc, char ch,char ch2) { //先处理小括号 while(1) { int posEnd = strSrc.find(ch); if(posEnd < 0) return true; else if(posEnd == 0) { cout << ch <<"缺少对应的左括号" << endl; return false; }else { //找到与之对应的大括号 int i = posEnd -1; while(i >=0 && strSrc.at(i) != ch2) i--; if(i < 0) { cout << ch << "没有与之配对的左括号" << endl; return false; } string tmp = strSrc.substr(i+1,posEnd - i-1); //截取()之间的字符串 string strout=""; if(DealSmple(tmp,strout)) //处理()之间的公式,并返回处理结果 { strSrc = strSrc.substr(0,i) + strout + strSrc.substr(posEnd+1,strSrc.length() - posEnd); //cout << "DealSmple " << ch << " " << strSrc << endl; }else return false; } } return true; } int main() { string strSrc,strout = ""; cout << "请输入公式,以=号结束:" << endl;; getline(cin,strSrc); if(!isValid(strSrc)) return 0; if(!DealKuhao(strSrc,')','(')) return 0; if(!DealKuhao(strSrc,']','[')) return 0; if(!DealKuhao(strSrc,'}','{')) return 0; DealSmple(strSrc,strout); cout << strout << endl; return 0; }
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥15 乌班图ip地址配置及远程SSH
- ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
- ¥15 PSPICE制作一个加法器
- ¥15 javaweb项目无法正常跳转
- ¥15 VMBox虚拟机无法访问
- ¥15 skd显示找不到头文件
- ¥15 机器视觉中图片中长度与真实长度的关系
- ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
- ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
- ¥15 java 的protected权限 ,问题在注释里