结对项目2.0版
更新内容:
1.在之前基础上实现四个数的四则运算。
2.实现了带有括号的运算。
存在问题:
运算过程中偶尔会有-nan(ind)的结果,还在找原因。
部分代码如下:

1 //运算符栈的长度
2 #define OPSTACK_LENGTH 5
3 //操作数栈的长度
4 #define NUMSTACK_LENGTH 100
5 //输入串的最大长度
6 #define MAX_STRING_LENGTH 100
7 #pragma warning(disable:4996)
8 //表达式结构体
9 struct biaodashi
10 {
11 char word;
12 };
13 //运算符结构体
14 struct operatorStruct
15 {
16 //运算符名称
17 char name;
18 //优先级
19 int priority;
20 //目数,即操作数个数,例如单目运算符为1,双目运算符2
21 int opnum;
22 };
23
24 typedef struct operatorStruct OPERATOR;
25
26 //运算符栈
27 OPERATOR opStack[OPSTACK_LENGTH];
28 //运算符栈顶指针
29
30 //操作数栈
31 double numStack[NUMSTACK_LENGTH];
32 //操作数栈顶指针
33 int opStackTop = -1;
34 int numStackTop = -1;
35
36 //获取一个字符所代表的运算符的优先级
37 int getPriority(char name)
38 {
39 if (name == '(' || name == ')')
40 {
41 return 0;
42 }
43 if (name == '!')
44 {
45 return 3;
46 }
47 if (name == '*' || name == '/')
48 {
49 return 2;
50 }
51 if (name == '+' || name == '-')
52 {
53 return 1;
54 }
55
56 }
57 //获取一个字符所代表的运算符的目数
58 int getOpNum(char name)
59 {
60 if (name == '*' || name == '/' || name == '+' || name == '-')
61 {
62 return 2;
63 }
64 if (name == '!')
65 {
66 return 1;
67 }
68 if (name == '(' || name == ')')
69 {
70 return 0;
71 }
72
73 }
74
75 //运算符压栈
76 void pushOperator(OPERATOR op)
77 {
78 if (opStackTop < OPSTACK_LENGTH - 1)
79 {
80 opStack[++opStackTop] = op;
81 }
82 }
83 //运算符出栈
84 OPERATOR popOperator()
85 {
86 if (opStackTop >= 0)
87 {
88 return opStack[opStackTop--];
89 }
90 }
91 //操作数压栈
92 void pushNumber(double num)
93 {
94 if (numStackTop < NUMSTACK_LENGTH - 1)
95 {
96 numStack[++numStackTop] = num;
97 }
98 }
99 //操作数出栈
100 double popNumber()
101 {
102 if (numStackTop >= 0)
103 {
104 return numStack[numStackTop--];
105 }
106 }
107
108 //从操作数栈中弹出两个操作数,完成一次双目运算
109 double opertate2Num(OPERATOR op)
110 {
111 double num2 = popNumber();
112 double num1 = popNumber();
113 if (op.name == '+')
114 {
115 return num1 + num2;
116 }
117 if (op.name == '-')
118 {
119 return num1 - num2;
120 }
121 if (op.name == '*')
122 {
123 return num1 * num2;
124 }
125 if (op.name == '/')
126 {
127 return num1 / num2;
128 }
129 }
130 //从操作数栈中弹出一个操作数,完成一次单目运算
131 double opertate1Num(OPERATOR op)
132 {
133 double num = popNumber();
134 if (op.name == '!')
135 {
136 double result = 1;
137 while (num > 1)
138 {
139 result *= num;
140 num--;
141 }
142 return result;
143 }
144
145 }
146 //完成一次运算
147 double operate(OPERATOR op)
148 {
149 if (op.opnum == 1)
150 {
151 return opertate1Num(op);
152 }
153 else if (op.opnum == 2)
154 {
155 return opertate2Num(op);
156 }
157
158 }
159 //四则运算计算器
160 double Calculate(struct biaodashi *string)
161 {
162
163 int i;
164 OPERATOR op, topOp;//op为从当前输入串中提取的一个运算符,topOp为运算符栈栈顶的运算符
165
166 topOp.name = '#';
167 topOp.priority = 0;
168 topOp.opnum = 0;
169 pushOperator(topOp);//压入#作为初始运算符
170
171 for (i = 0; string[i].word != '=';i++)
172 {
173 //从输入串中取出一个字符作为开始,进行处理,直到表达式结束
174 if (string[i].word!='+' && string[i].word != '-'&& string[i].word != '*'&& string[i].word != '/'&& string[i].word != '('&& string[i].word != ')')
175 {
176 //如果是操作数,将整个操作数提取出来,压入操作数栈
177 pushNumber((double)(string[i].word));
178 }
179 else
180 {
181 op.name = string[i].word;
182 op.priority = getPriority(string[i].word);
183 op.opnum = getOpNum(string[i].word);
184 topOp = popOperator();
185 if (op.name == '(')
186 {
187 //如果是'(',将从栈顶弹出的运算符压回栈内,并将当前运算符则压栈
188 pushOperator(topOp);
189 pushOperator(op);
190 }
191 else if (op.name == ')')
192 {
193 //如果是')',则进行运算,每次运算结果作为一个操作数压入操作数栈,直到将'('弹出运算符栈
194 while (topOp.name != '(')
195 {
196 pushNumber(operate(topOp));
197 topOp = popOperator();
198 }
199 }
200 else
201 {
202 //如果是普通运算符
203 if (topOp.name != '#' && op.priority <= topOp.priority)
204 {
205 //如果运算符栈非空,且当前运算符的优先级大于栈顶运算符,则进行一次运算,将结果压入操作数栈
206 pushNumber(operate(topOp));
207 }
208 else
209 {
210 //否则将从栈顶弹出的运算符压回
211 pushOperator(topOp);
212 }
213 //将当前运算符压栈
214 pushOperator(op);
215 }
216 }
217
218 }
219 //完成栈内剩余的运算
220 while ((topOp = popOperator()).name != '#')
221 {
222 pushNumber(operate(topOp));
223 }
224 //操作数栈中剩下的最后一个数即为结果
225 return popNumber();
}
部分主函数代码。
1 for (i = 0; i < N; i++)
2 {
3 num1 = rand() % 100 + 1; //生成随机数
4 num2 = rand() % 100 + 1;
5 num3 = rand() % 100 + 1;
6 num4 = rand() % 100 + 1;
7 optr1 = rand() % 4;
8 optr2 = rand() % 4;
9 optr3 = rand() % 4;
10 kuohao = rand() % 8;
11 if (num1 > 40)
12 {
13 printf("题号:%d\n", i + 1);
14 printf("%d %c %d %c %d %c %d=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
15 string[0].word = num1;
16 string[1].word = str[optr1];
17 string[2].word = num2;
18 string[3].word = str[optr2];
19 string[4].word = num3;
20 string[5].word = str[optr3];
21 string[6].word = num4;
22 string[7].word = '=';
23 answer1 = Calculate(string);
24 scanf("%lf", &answer2);
25 ch = getchar();
26 if ((fabs(answer2-answer1))<0.01)
27 printf("正确\n");
28 else printf("错误 正确答案是:%-10.2lf\n", answer1);
29 }
输出结果:

结果:可以看到第6题出现了-nan(ind)的问题,百度一下意思是not a number,应该是计算过程中出了问题,但是还没找到。

浙公网安备 33010602011771号