首页 > 代码库 > 结对项目2.0版

结对项目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         else180         {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             else201             {202                 //如果是普通运算符  203                 if (topOp.name != # && op.priority <= topOp.priority)204                 {205                     //如果运算符栈非空,且当前运算符的优先级大于栈顶运算符,则进行一次运算,将结果压入操作数栈  206                     pushNumber(operate(topOp));207                 }208                 else209                 {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,应该是计算过程中出了问题,但是还没找到。

结对项目2.0版