万用计算器函数,接受数学算式字符串为参数——考虑运算顺序、可无限嵌套括号、支持加、减、乘、除、乘方运算!
使用方法:long SzCal(const char* const sz), 其中sz为算式,如"15+6" "589*78"等。乘方符号为^, 如2的16次方表示为"2^16"。返回值为运算结果。例: long lResult = SzCal("(1*(5-6)+4)^3"); // lResult == 27
代码如下(头文件<cmath>):
由于是以字符串为参数,所以无论是console还是windows程序都能使用,只是一些console标准流的输出在windows程序中需稍稍修改(如cerr改为MessageBox)。
需声明using namespace std;
程序代码:
const long SzCal(const char* const sz) { int i = 0; return SzCal(sz, i); } const long SzCal(const char* const sz, int& i) { long n1 = 0, n2 = 0; char szTemp[500] = {0}; int j = 0, k = 0; char op = 0; if (sz[i] == '(') // 若是左括号,则递归处理,并将括号值付给操作数1 { i++; n1 = SzCal(sz, i); } else { for (j = 0; isdigit(sz[i]); i++, j++) // 读入操作数1 szTemp[j] = sz[i]; szTemp[j] = '\0'; n1 = atol(szTemp); } while (sz[i] != '\0' && sz[i] != ')') { op = sz[i]; // 获取运算符 i++; if (sz[i] == '(') // 若是左括号,则递归处理,并将括号值付给操作数2 { i++; n2 = SzCal(sz, i); } else { for (j = 0; isdigit(sz[i]); i++, j++) // 读入操作数2 szTemp[j] = sz[i]; szTemp[j] = '\0'; n2 = atol(szTemp); } switch (op) // 运算 { case '+': DoAdd(sz, i, n1, n2); break; case '-': DoSubtract(sz, i, n1, n2); break; case '*': DoMultiply(sz, i, n1, n2); break; case '/': DoDivide(sz, i, n1, n2); break; case '%': DoMod(sz, i, n1, n2); break; case '^': n1=pow((double)n1, (double)n2); break; default: cerr << "\aError: Operator error \n"; exit(1); } } i += sz[i] == ')' ? 1 : 0; // 跳过右括号 return n1; } void DoMultiply(const char* const sz, int& i, long& n1, long& n2) { long n3 = 0; int j = 0; char op = 0; char szTemp[500] = {0}; if (sz[i] == '^') // ^的优先级更高 { op = sz[i]; while (op == '^') { i++; if (sz[i] == '(') n3 = SzCal(sz, i); else { for (j=0; isdigit(sz[i]); i++, j++) szTemp[j] = sz[i]; szTemp[j] = '\0'; n3 = atol(szTemp); } n2 = pow((double)n2, (int)n3); op = sz[i]; } n1 *= n2; } else n1 *= n2; } void DoDivide(const char* const sz,int& i, long& n1, long& n2) { long n3 = 0; int j = 0; char op = 0; char szTemp[500] = {0}; if (sz[i] == '^') // ^的优先级更高 { op = sz[i]; while (op == '^') { i++; if (sz[i] == '(') n3 = SzCal(sz, i); else { for (j = 0; isdigit(sz[i]); i++, j++) szTemp[j] = sz[i]; szTemp[j] = '\0'; n3 = atol(szTemp); } n2 = pow((double)n2, (int)n3); op = sz[i]; } if (n2 == 0) { cerr << "\aError: Divided error \n"; exit(1); } n1 /= n2; } else { if (n2 == 0) { cerr << "\aError: Divided error \n"; exit(1); } n1 /= n2; } } void DoAdd(const char* const sz, int& i, long& n1, long& n2) { long n3 = 0; int j = 0; char op = 0; char szTemp[500] = {0}; if (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^') { op = sz[i]; while (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^') { i++; if (sz[i] == '(') n3 = SzCal(sz, i); else { for (j = 0; isdigit(sz[i]); i++, j++) szTemp[j] = sz[i]; szTemp[j] = '\0'; n3 = atol(szTemp); } switch (op) { case '*': DoMultiply(sz, i, n2, n3); break; case '/': DoDivide(sz, i, n2, n3); break; case '%': DoMod(sz, i, n2, n3); break; case '^': n2 = pow((double)n2, (int)n3); break; } op = sz[i]; } n1 += n2; } else n1 += n2; } void DoSubtract(const char* const sz, int& i, long& n1, long& n2) { long n3 = 0; int j = 0; char op = 0; char szTemp[500] = {0}; if (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^') { op = sz[i]; while (sz[i] == '*' || sz[i] == '/' || sz[i] == '%' || sz[i] == '^') { i++; if (sz[i] == '(') n3 = SzCal(sz, i); else { for (j = 0; isdigit(sz[i]); i++, j++) szTemp[j] = sz[i]; szTemp[j] = '\0'; n3 = atol(szTemp); } switch (op) { case '*': DoMultiply(sz, i, n2, n3); break; case '/': DoDivide(sz, i, n2, n3); break; case '%': DoMod(sz, i, n2, n3); break; case '^': n2 = pow((double)n2, (int)n3); break; } op = sz[i]; } n1 -= n2; } else n1 -= n2; } void DoMod(const char* const sz, int& i, long& n1, long& n2) { long n3 = 0; int j = 0; char op = 0; char szTemp[500] = {0}; if (sz[i] == '^') // ^的优先级更高 { op = sz[i]; while (op == '^') { i++; if (sz[i] == '(') n3 = SzCal(sz, i); else { for (j = 0; isdigit(sz[i]); i++, j++) szTemp[j] = sz[i]; szTemp[j] = '\0'; n3 = atol(szTemp); } n2 = pow((double)n2, (int)n3); op = sz[i]; } if (n2 == 0) { cerr << "\aError: Divided error \n"; exit(1); } n1 %= n2; } else { if (n2 == 0) { cerr << "\aError: Mod error \n"; exit(1); } n1 %= n2; } }