表达式求值

来源:互联网 发布:淘宝汉服睡衣店铺推荐 编辑:程序博客网 时间:2024/06/16 09:30
#include<stack>#include<iostream>#include<fstream>#include<vector>#include<string>using namespace std;//template<class T>//input.txt文本文件内容://2 * (4 - 100) =//3 * 5 + 9 / 3 =//100 - 20 * (4 * 6 / 3) =//(135 + 75) / (14 * 5) =//120 - 60 / 5 * 5 =//128 - 6 * 8 / 16 =//330 / (65 - 50) =////生成的output.txt文本文件内容://2 * (4 - 100) = -192//3 * 5 + 9 / 3 = 18//100 - 20 * (4 * 6 / 3) = -60//(135 + 75) / (14 * 5) = 3//120 - 60 / 5 * 5 = 60//128 - 6 * 8 / 16 = 125//330 / (65 - 50) = 22typedef struct Dates{string Exp;int Result;}Datas;typedef struct{Datas *base;int length;}AList;class Express{private:AList List;public:Express();void Read(char*name);bool Check(string Str);bool ck1(string Str);bool ck2(string Str);void Write(char*name);void calculate();void show();void show2();char Precede(char c1,char c2);int  Operator(int a, char theta, int b);bool IN(char ch);bool Matching(string Str);};bool Express::Matching(string Str){int flag = 1;Str += '#';int n = 0;char ch;stack<char>S;ch = Str[n]; n++;while (ch != '#'&&flag){switch (ch){case'(':S.push(ch); break;case')':if (!S.empty())S.pop();elseflag = 0; break;}if (n < Str.length()){ch = Str[n]; n++;}}if (S.empty() && flag)return true;else return false;}void Express::show2(){cout << "************************************题目列表如下(可见于input.txt)*****************************************" << endl;for (int i = 0; i < List.length; i++){cout <<"                                        "<< List.base[i].Exp << "="  << endl;}cout << "****************************************************************************************************************" << endl;}bool Express::IN(char ch){if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#'){return true;}else{return false;}}int Express::Operator(int a, char theta, int b){switch (theta){case '+':return a + b;case '-':return a - b;case '*':return a*b;case '/':return a / b;}return 0;}char Express::Precede(char c2, char c1){int i, j;char Table[8][8] = { ' ','+','-','*','/','(',')','#',                 '+','>','>','<','<','<','>','>',                   '-','>','>','<','<','<','>','>',                 '*','>','>','>','>','<','>','>',                 '/','>','>','>','>','<','>','>',                 '(','<','<','<','<','<','=','> ',                 ')','>','>','>','>','> ','>','>',                 '#','<','<','<','<','<','<','=', };           //优先级表格for (i = 0; i < 8; i++)if (Table[0][i] == c1)          //纵坐标寻找break;for (j = 0; j < 8; j++)           //横坐标寻找if (Table[j][0] == c2)break;return Table[j][i];}void Express::calculate(){for (int i = 0; i < List.length; i++){int a,d,b,n = 0;char x,c;stack<char> ch;stack<int>in;List.base[i].Exp += '#';ch.push('#');c = List.base[i].Exp[n]; n++;x = ch.top();while (c != '#' || x != '#'){if (!IN(c)){if (c >= '0'&&c <= '9'){d = 0;while (c >= '0'&&c <= '9'){d = d * 10 + c - '0';if (n < List.base[i].Exp.length()){c = List.base[i].Exp[n]; n++;}}in.push(d);}}else{switch (Precede(ch.top(), c)){case'<':ch.push(c); if (n < List.base[i].Exp.length()) { c = List.base[i].Exp[n]; n++; }break;case'>':x = ch.top();ch.pop();b = in.top();in.pop();a = in.top();in.pop();in.push(Operator(a,x, b));break;case'=':x = ch.top();ch.pop();if (n < List.base[i].Exp.length()) { c = List.base[i].Exp[n]; n++; }break;}}}List.base[i].Result = in.top();in.pop();List.base[i].Exp = List.base[i].Exp.substr(0,List.base[i].Exp.length() - 1);}}bool  Express::ck1(string Str){char*p;p = &Str[0];while (*p != NULL){if ((*p>39 && *p<58)||*p=='='){p++;}else{cout << "                                        " << "表达式存在无意义字符:" << Str << endl;return false;}}return true;}bool  Express::ck2(string Str){char*p;p = &Str[0];if (ck1(Str)){while (*p != NULL){if (*p == '/' || *p == '*' || *p == '+' || *p == '-'){char*q;q = p;q++;if (*q == '/' || *q == '*' || *q == '+' || *q == '-'){cout << "                                        " << "两个运算符之间不能一起运算:" << Str << endl;return false;}}p++;}p--;if (*p == '/' || *p == '*' || *p == '+' || *p == '-'){cout<<"                                        " << "最后一个字符为运算符,无意义:" << Str << endl;return false;}else if(*p=='='){p--;if (*p == '/' || *p == '*' || *p == '+' || *p == '-'){cout << "                                        " << "最后一个字符为运算符,无意义:" << Str << endl;return false;}return true;}else{return true;}}else{return false;}}bool Express::Check(string Str){char*p;char*q;char*T;string Temp;if (ck2(Str)){for (int i = 0; i < Str.length(); i++){if (Str[i] == '(' || Str[i] == ')'){Temp += Str[i];}}if (Temp.length() == 0) { return true; }if (Temp.length() % 2 == 1){cout << "                                        " <<"缺少括号:"  << Str<< endl;return false;}else{if (Matching(Str)){return true;}else{cout << "                                        " << "括号匹配出现问题:" << Str << endl;return false;}}}else{return false;}return true;}Express::Express(){List.base = new Datas[100];List.length = 0;}void Express::show(){cout << "************************************计算结果如下(可见于output.txt)****************************************" << endl;for (int i = 0; i < List.length; i++){cout << "                                         " << List.base[i].Exp<<"="<<List.base[i].Result<<endl;}cout << "****************************************************************************************************************" << endl;}void Express::Read(char*name){ifstream in;in.open(name, ios::in);Dates D;if (in.fail()){cout << "打开文件失败,确认文件名为inexp 后缀名txt" << endl;exit(1);}while (!in.eof()){string x;in >> x;if (Check(x)){if (x.size() == 0){break;}if (x.find('=') < 100){D.Exp = x.substr(0, x.find('='));}else{D.Exp = x;}D.Result = 0;List.base[List.length] = D;List.length++;}}in.close();}void Express::Write(char*name){ofstream out;out.open(name, ios::out | ios::ate);if (out.fail()){cout << "请添加写入文件名outexp 后缀名txt" << endl;exit(1);}for (int i = 0; i < List.length;i++){out <<List.base[i].Exp<< "=" << List.base[i].Result << endl;}out.close();}int main(){int S;cout << "************************************错误表达式如下(已排除!)***********************************************" << endl;Express Exp;Exp.Read("input.txt");Exp.show2();cout << "是否进行计算?(!0)" << endl;cin >> S;if (S){Exp.calculate();Exp.Write("output.txt");}Exp.show();}

0 0