一个存在一些问题的程序
这个程序的思路:先举个例子:2*((2+2)*2))
首先,两个数之间必定会有运算符,其次,一个式子的最左端要么是一个数字,要么是一个左括号。
由于这个程序只涉及加减乘除,故只需要获得两个运算符就可以对其进行化简。
如:2*3+4-->6+4;2*3*4-->6*4;2+3*4-->2+12;
假设输入的式子是正确的
输入一个式子,先读一个数,若失败,那么第一个符号必定是左括号,并且这个左括号和与其匹配的右括号之间的内容也构成一个式子,因此,遇到左括号便可递归调用求解式子的函数。
若成功,继续读取第一个运算符,第二个数字,第二个运算符,第三个数字,读取三个数字之后便可化简,然后继续读第二个运算符,第三个数字,再化简,期间若遇到右括号或换行符,说明这一层式子计算完成,返回主调函数。
但是当输入的式子在格式上有问题时,就会出现各种尴尬的局面
程序代码:
#include <stdio.h> #include <math.h> #include <ctype.h> #define LENGTH 3 #define WIDTH 2 int FLAG; //FALG == 1 说明式子格式正确,FLAG == 0 说明式子格式错误 const char PRIORITY[LENGTH][WIDTH] = { {'+', '-'}, {'*', '/'}, {'(', ')'} }; //定义运算符优先级 size_t priority(char); //确定运算符优先级等级 double operation(double, char, double); //返回两个值运算后的结果 void simplificat(double *, char *, double *, char *, double *); //化简式子 char read_operator(void); //读取下一个运算符 double read_num(void); //读取下一个数字 double formula(void); //求解式子的值 int main(void) { while (FLAG = 1) { double result = formula(); if (FLAG) printf("\nresult = %g\n\n\n", result); else { printf("\n格式错误\n\n\n"); } } return 0; } size_t priority(char operator_) //确定运算符优先级等级 { for (size_t i = 0; i < LENGTH; i++) for (size_t j = 0; j < WIDTH; j++) if (operator_ == PRIORITY[i][j]) return i; if (operator_ != '\n') FLAG = 0; return LENGTH; } double operation(double num_1, char operator_, double num_2) { switch (operator_) { case '+': num_1 += num_2; break; case '-': num_1 -= num_2; break; case '*': num_1 *= num_2; break; case '/': if (fabs(num_2) < 1e-6) FLAG = 0; else num_1 /= num_2; break; } return num_1; } void simplificat(double *num_1, char *operator_1, double *num_2, char *operator_2, double *num_3) { if (priority(*operator_1) >= priority(*operator_2)) { *num_1 = operation(*num_1, *operator_1, *num_2); *operator_1 = *operator_2; *num_2 = *num_3; } else *num_2 = operation(*num_2, *operator_2, *num_3); } char read_operator(void) { char operator_; while (isspace(operator_ = getchar()) && operator_ != '\n');//跳过空白符 return operator_; } double read_num(void) { double num = 0; if (!scanf("%lf", &num)) { if (getchar() == '(')//如果是左括号,那么计算括号内的值 num = formula(); else FLAG = 0; } return num; } double formula(void) { double num_1 = 0, num_2 = 0, num_3; char operator_12 = 0, operator_23 = 0; if (FLAG) num_1 = read_num(); if (FLAG) operator_12 = read_operator(); if (!FLAG) return 0; if (operator_12 == ')' || operator_12 == '\n') return num_1; if (FLAG) num_2 = read_num(); while (1) { if (FLAG) operator_23 = read_operator(); if (!FLAG) return 0; if (operator_23 == ')' || operator_23 == '\n') return operation(num_1, operator_12, num_2); if (FLAG) num_3 = read_num(); simplificat(&num_1, &operator_12, &num_2, &operator_23, &num_3); } }