结对项目2.0版

Posted 悦然品茗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结对项目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,应该是计算过程中出了问题,但是还没找到。

 
 
 

以上是关于结对项目2.0版的主要内容,如果未能解决你的问题,请参考以下文章

结对编程

结对项目-小学生四则运算系统网页版项目报告

结对项目-四则运算出题程序(GUI版)

结对-四则运算答题器-开发环境搭建过程

小学四则运算练习题网页版结对项目报告

结对作业