导航

结对项目2.0版

Posted on 2016-10-12 23:22  圆润的馒头君  阅读(230)  评论(1编辑  收藏  举报

更新内容:

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();    
226 }
View Code

这部分为计算器,主体来自http://blog.csdn.net/bhq2010/article/details/7516369,做了些必要的修改。

 1 int N = 0, i = 0;
 2     int optr1 = 0, optr2 = 0, optr3 = 0, kuohao = 0;
 3     int num1, num2, num3, num4;
 4     
 5     double answer1, answer2;
 6     struct biaodashi string[15];
 7     char str[] = "+-*/", ch;
 8 
 9     srand((unsigned)time(0));
10 
11     printf("请输入本次测试的题目数量:");        //手动输入题目数量
12     scanf("%d", &N);
13     ch = getchar();
14 
15     printf("保留两位小数\n");                    //输入结果如果有小数,保留两位小数
View Code

 部分主函数代码。

 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         }

这部分为不带括号的出题方式,比例大小为60%

else
                    {
                        printf("题号:%d\n", i + 1);
                        switch (kuohao)
                        {
                        case 1:
                            printf("(%d %c %d) %c %d %c %d=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = '(';
                            string[1].word = num1;
                            string[2].word = str[optr1];
                            string[3].word = num2;
                            string[4].word = ')';
                            string[5].word = str[optr2];
                            string[6].word= num3;
                            string[7].word = str[optr3];
                            string[8].word = num4;
                            string[9].word = '=';
                            break;
                        case 2:
                            printf("(%d %c %d %c %d) %c %d=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = '(';
                            string[1].word = num1;
                            string[2].word = str[optr1];
                            string[3].word = num2;
                            string[4].word = str[optr2];
                            string[5].word = num3;
                            string[6].word = ')';
                            string[7].word = str[optr3];
                            string[8].word = num4;
                            string[9].word = '=';
                            break;
                        case 3:
                            printf("%d %c (%d %c %d) %c %d=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = num1;
                            string[1].word = str[optr1];
                            string[2].word = '(';
                            string[3].word = num2;
                            string[4].word = str[optr2];
                            string[5].word = num3;
                            string[6].word = ')';
                            string[7].word = str[optr3];
                            string[8].word = num4;
                            string[9].word = '=';
                            break;
                        case 4:
                            printf("%d %c (%d %c %d %c %d)=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = num1;
                            string[1].word = str[optr1];
                            string[2].word = '(';
                            string[3].word = num2;
                            string[4].word = str[optr2];
                            string[5].word = num3;
                            string[6].word = str[optr3];
                            string[7].word = num4;
                            string[8].word = ')';
                            string[9].word = '=';
                            break;
                        case 5:
                            printf("%d %c %d %c (%d %c %d)=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = num1;
                            string[1].word = str[optr1];
                            string[2].word = num2;
                            string[3].word= str[optr2];
                            string[4].word = '(';
                            string[5].word = num3;
                            string[6].word = str[optr3];
                            string[7].word = num4;
                            string[8].word = ')';
                            string[9].word = '=';
                            break;
                        case 6:
                            printf("(%d %c %d) %c (%d %c %d)=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = '(';
                            string[1].word = num1;
                            string[2].word = str[optr1];
                            string[3].word = num2;
                            string[4].word = ')';
                            string[5].word = str[optr2];
                            string[6].word = '(';
                            string[7].word = num3;
                            string[8].word = str[optr3];
                            string[9].word = num4;
                            string[10].word = ')';
                            string[11].word = '=';
                            break;
                        case 7:
                            printf("(%d %c (%d %c %d)) %c %d=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = '(';
                            string[1].word = num1;
                            string[2].word = str[optr1];
                            string[3].word = '(';
                            string[4].word = num2;
                            string[5].word = str[optr2];
                            string[6].word = num3;
                            string[7].word = ')';
                            string[8].word = ')';
                            string[9].word = str[optr3];
                            string[10].word = num4;
                            string[11].word = '=';
                            break;
                        case 8:
                            printf("%d %c (%d %c (%d %c %d))=?\n", num1, str[optr1], num2, str[optr2], num3, str[optr3], num4);
                            string[0].word = num1;
                            string[1].word = str[optr1];
                            string[2].word = '(';
                            string[3].word = num2;
                            string[4].word = str[optr2];
                            string[5].word= '(';
                            string[6].word = num3;
                            string[7].word = str[optr3];
                            string[8].word = num4;
                            string[9].word = ')';
                            string[10].word = ')';
                            string[11].word = '=';
                            break;
                        default: printf("错误\n");
                        }
                        answer1 = Calculate(string);
                        scanf("%lf", &answer2);
                        ch = getchar();

                        if ((fabs(answer2-answer1))<0.01)
                            printf("正确\n");
                        else printf("错误 正确答案是:%-10.2lf\n", answer1);
                    }
View Code

带括号的出题方式采用的枚举法,所以略长,比例为40%

输出结果:

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