• 结对项目总结


    经过多个礼拜的编程,最终终于完成了结对项目。

    本次结对项目是基于上次的个人项目完成的。本质上来说,是将上回的计算功能模块化,再加入随机生成算式的功能模块,最后把他们附在界面上调用。

    完成项目

    1、随机生成算式

    2、能选择生成算式的长度

    3、能够选择生成算式中数字的位数和精度

    4、能够选择生成的括号数量(因为考虑到随机生成,所以控制的数量是括号的最大量而不是固定量)

    完整代码

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #include<time.h>
    #include<stack>
    
    using namespace std;
    #define N 1000
    int timer=0;
    int ri,wr=0;
    int chance=3;
    char infix[N];  //中缀表达式(未分离,都在一个字符串里)
    char infix2[N];
    char expression[N][10];    //保存预处理过的表达式,也就是每个元素都分离过的表达式
    char suffix[N][10];        //保存后缀表达式的操作数
    int count;//表达式中元素的个数(一个完整到数字(可能不止一位数)或者符号)
    int suffixLength;//后缀表达式的长度
    
    struct fra{
        char str[10];//为了在栈中记录符号,所以包括数字全部用char记录
        double up;//分子
        double down;//分母
    };
    int len = 0;
    FILE *fp = fopen("1.txt", "r");
    long answer;
    fra answer1,answer2;
    
    
    class cal{
    private:
        
        int level(char a){
            switch(a){
            case '#':return 0;
            case '+':
            case '-':return 1;
            case '*':
            case '/':return 2;
            case '^':return 3;
            default:break;
            }
            return -1;
        }
        
        int isDigital(char x){
            if( (x>='0'&&x<='9') )
                return 1;
            return 0;
        }
        
        int isNumber(char *str){
            int i;
            for(i=0;str[i];i++){
                if(isDigital(str[i])==0)return 0;
            }
            return 1;
        }
        /*************************************
        预处理中缀表达式,把连续的字符分离成不同的元素,用字符串数组(expression[][])
        保存,方便后面的计算,因为这里考虑了运算数可能不全是个位数
        比如:(12+3)
        在处理成后缀表达式时,是123+,容易产生歧义(1+23 ? 12+3)
        *************************************/
        void pretreatment(char *str){
            int i,j,numberFlag;
            char temp[3];
            char number[10];
            count=0;
            numberFlag=0;
            for(j=0,i=0;str[i];i++){
                if(isDigital(str[i])==0){
                    if(numberFlag==1){
                        number[j]=0;
                        strcpy(expression[count++],number);
                        j=0;
                        numberFlag=0;
                    }
                    if(str[i]!=' '){
                        temp[0]=str[i];temp[1]=0;
                        strcpy(expression[count++],temp);
                    }
                }
                else {
                    numberFlag=1;
                    number[j++]=str[i];
                }
            }
            
            //    puts("分离后的表达式为");
            //   for(i=0;i<count;i++){
            //       printf("%s ",expression[i]);
            //   }puts("");
            //    puts("");
        }
        /*****************************************
        中缀表达式 转 后缀表达式
        
          遍历字符串,对于str[i]
          str[i]是运算数(或者是字母代替的运算变量)输出;
          str[i]是符号,有两种情况
          (1),是右括号,栈顶元素输出,直到与str[i]匹配的左括号出栈(左括号不用输出打印)
          (2),是运算符,判断str[i]与栈顶元素的优先级,str[i]优先级 不高于 栈顶符号,则栈
          顶元素输出,直到栈空 或者 栈顶符号优先级低于str[i]
        *****************************************/
        void infix_to_suffix(char str[N][10]){
            
            memset(suffix,0,sizeof(suffix));
            suffixLength=0;
            
            stack <char*> st;
            int i=0;
            char Mark[2]="#";
            st.push(Mark);
            do{
                if(isNumber(str[i])==1)//运算数直接保存到后缀表达式中
                    strcpy(suffix[suffixLength++],str[i]);
                else if(str[i][0]=='(')        //是 左括号,直接入栈
                    st.push(str[i]);
                else if(str[i][0]==')'){        //是 右括号,栈顶出栈,直到与其匹配的左括号出栈
                    while( strcmp(st.top(),"(")!=0 ){
                        char temp[10];
                        strcpy(temp,st.top());
                        strcpy(suffix[suffixLength++],temp);
                        st.pop();
                    }
                    st.pop();
                }
                else if( strcmp(st.top(),"(")==0 )//是 运算符,且栈顶是左括号,则该运算符直接入栈
                    st.push(str[i]);
                else {                    //是 运算符,且栈顶元素优先级不小于运算符,则栈顶元素一直
                    //出栈,直到 栈空 或者 遇到一个优先级低于该运算符的元素
                    while( !st.empty() ){
                        char temp[10];
                        strcpy(temp,st.top());
                        if( level(str[i][0]) > level(temp[0]) )
                            break;
                        strcpy(suffix[suffixLength++],temp);
                        st.pop();
                    }
                    st.push(str[i]);
                }
                i++;
            }while(str[i][0]!=0);
            
            while( strcmp(st.top(),"#")!=0 ){        //将栈取空结束
                char temp[10];
                strcpy(temp,st.top());
                strcpy(suffix[suffixLength++],temp);
                st.pop();
            }
            
            //   puts("后缀表达式为:");
            //  for(i=0;i<suffixLength;i++){
            //      printf("%s",suffix[i]);
            //  }puts("");
            //  puts("");
        }
        //////////////////////////////////////////////////
        int gcd(int a,int b) {          //最大公约数
            if(b == 0)
                return a;
            else
                return gcd(b,a % b);
        }
        
        void simplify(fra aaa){
            
            int a=gcd(aaa.down,aaa.up);
            aaa.up=aaa.up/a;
            aaa.down=aaa.down/a;
            //    printf("%.1lf/%.1lf\n",aaa.up,aaa.down);
            //    puts("计算出后缀表达式的结果:");
            /*        if(aaa.down==1)
            {
            printf("%lf\n",aaa.up);
            }    
            else
            {
            printf("%lf/%lf\n",aaa.up,aaa.down);
            }
            */
            if(timer==0)
            {
                answer1.up=aaa.up;
                answer1.down=aaa.down;
                timer++;
            }
            else
            {
                answer2.up=aaa.up;
                answer2.down=aaa.down;
                timer--;
            }
            //       printf("%d\n%lf  %lf\n%lf  %lf\n",timer,answer1.up,answer1.down,answer2.up,answer2.down);
        }
        
        /**************************************
        计算后缀表达式的值
        **************************************/
        fra kt[N];
        int stackTop;
        void getResult(char str[N][10]){
            //    fra fras[N];
            stackTop=0;
            /*这里要注意,内存的分配方案导致 i 的位置就在temp[9]旁边,然后strcpy()函数直接拷贝内存的话,在temp越界情况下会覆盖 i 的值*/
            int i;
            //   double temp;
            for(i=0;i<suffixLength;i++){
                if(isNumber(str[i])==1){
                    // strcpy(kt[stackTop++].str,str[i]);
                    kt[stackTop].up=atof(str[i]);
                    kt[stackTop].down=1;
                    stackTop++;
                }
                else {
                    //            char a[10],b[10];
                    fra na,nb,nc;
                    
                    //  strcpy(a,kt[stackTop-1].str);
                    na.up = kt[stackTop-1].up;
                    na.down=kt[stackTop-1].down;
                    //fras[stackTop-1].up=na;
                    //fras[stackTop-1].down=1;
                    stackTop--;
                    
                    //    strcpy(b,kt[stackTop-1].str);
                    nb.up = kt[stackTop-1].up;
                    nb.down=kt[stackTop-1].down;
                    //fras[stackTop-1].up=nb;
                    //fras[stackTop-1].down=1;
                    stackTop--;
                    
                    if(str[i][0]=='+')
                    {
                        nc.down=nb.down*na.down;
                        nc.up=nb.up*na.down+na.up*nb.down;
                    }
                    else if(str[i][0]=='-')
                    {
                        nc.down=nb.down*na.down;
                        nc.up=nb.up*na.down-na.up*nb.down;
                    }
                    else if(str[i][0]=='*')
                    {
                        nc.up=nb.up*na.up;
                        nc.down=nb.down*na.down;
                        
                    }
                    else if(str[i][0]=='/')
                    {
                        nc.down=nb.down*na.up;
                        nc.up=nb.up*na.down;
                    }
                    // sprintf(temp,"%lf",nc);
                    //strcpy(kt[stackTop++].str,temp);
                    kt[stackTop].down=nc.down;
                    kt[stackTop].up=nc.up;
                    stackTop++;
                }
            }
            sprintf(kt[stackTop-1].str,"%lf",kt[stackTop-1].up/kt[stackTop-1].down);
            //strcpy(kt[stackTop++],temp);
            
            /*    char as[N];
            gets(as);
            if(as==kt[stackTop-1].str)
            puts(" right");
            else{
            puts("wrong");
            }
            */
            simplify(kt[stackTop-1]);
            
            for(i=0;i<suffixLength;i++){
                memset(infix,0,sizeof(infix)); 
                memset(suffix,0,sizeof(suffix));
                memset(expression,0,sizeof(expression));
            }
            
            
        }
        //    char szTest[1000] = {0};
        
        
        void checkanswer()
        {
            //    getchars();
            //       printf("%d/%d\n%d/%d",answer1.up,answer1.down,answer2.up,answer2.down);
            if(answer1.up==answer2.up&&answer1.down==answer2.down)
            {
                printf("right\n");    
                ri++;
            }
            else{
                printf("wrong");
                if(answer1.down!=1)
                {
                    printf("\nthe answer is %lf/%lf\n",answer1.up,answer1.down);
                }
                else{
                    printf("\nthe answer is %lf\n",answer1.up);
                }wr++;
            }
        }
        
    public:
        void getanswer(char str[N]){
        //    gets
                    char temp[N];
            strcpy(temp,str);
            pretreatment( strcat(temp," ") );
            infix_to_suffix(expression);
            getResult(suffix);
                checkanswer();
                    printf("正确回答%d题\n错误回答%d题\n",ri,wr);
        }
        void work(char str[N])
        {
            char temp[N];
            
            // while(gets(infix)){
            //   getchars();
            
            
            // while(z<3){
            //  if(!feof(fp))
            //    {
            //        memset(infix, 0, sizeof(infix));
            //        fgets(infix, sizeof(infix) - 1, fp); // 包含了\n
            //        printf("%s", infix);        
            
            //    }
            //    getchars();
            //    printf("%s",str);
            strcpy(temp,str);
            pretreatment( strcat(temp," ") );
            infix_to_suffix(expression);
            getResult(suffix);
            //    getchars();
        
            
        
            
        }
    };
    class tuxinghua{
    private:
    int kh;//括号总数
    int stime;//左括号剩余可生成次数
    int lef;
        void fcheck(char str[N],int x){//符号检查
            char fuhao[2];
            //        srand((unsigned)time(NULL));  
            
            
            
            if(x>=0&&x<=21)
            {strcpy(fuhao,"+");}
            else if(x>=22&&x<=43)
            {strcpy(fuhao,"-");}
            else if (x>=44&&x<=65)
            {strcpy(fuhao,"*");}
            else if (x>=66&&x<=87)
            {strcpy(fuhao,"/");}
        //    else
        //    {printf("括号");}
            strncat(str,fuhao,1);
        }
        
        void ncheck(char str[N],int x){//数字检查
            char shuzi[2];
            int as;
            //    Sleep(10);
            //    srand((unsigned)time(NULL));  
            for(int i=0;i<x;i++)
            {
                //    int n=rand()%10;
                as=rand()%10;    
                //    printf("\n%d\n",rand()%100);
                sprintf(shuzi, "%d", as);
                strncat(str,shuzi,1);
            }
        }
    
    
    void  left(char str[N])
        {
        //    int i=x;
            char zuo[2];
            int b=rand()%3;
            if(b==1&&stime<=kh&&stime>=1){
            strcpy(zuo,"(");
            strncat(str,zuo,1);
    //    strncat(str,"(",2);
        //kh--;
        lef++;
        stime--;
            }
        
        
        }
    void right(char str[N]){
        int b=rand()%5;    
        char zuo[2];
        if(b==1&&lef>=1){
        strcpy(zuo,")");
            strncat(str,zuo,1);
    //    kh--;
        lef--;
            }
    }
    
    public:
        int tgetchars(char str[N]){
            if(    gets(str))
                return 1;
            else
                return 0;
        }
        
        
        int shengcheng(char str[N]){
            int clen;
            int max;
            int a=0;
            int f;
    lef=0;
            printf("输入长度(奇数)");
            scanf("%d",&clen);
            printf("数字取值范围(位数)");
            scanf("%d",&max);
            printf("最多括号个数");
            scanf("%d",&kh);
            stime=kh;
            srand((unsigned)time(NULL));  
            while(1)
            {
                while(a<clen)
            {
            f=rand()%88;
                
                if(a%2==0)
                {
                    left(str);
                    ncheck(str,max);
                }
                else
                {    
                    right(str);
                    fcheck(str,f);
                }
                a++;
                
            }
        
            if(lef==0)
                break;
            else {
        //        printf("aa");
            lef=0;
            memset(infix,0,sizeof(infix)); 
            a=0;
            stime=kh;
            continue;
        
            }
            
            }
            return 1;
        }
    };
    void main(){
        cal ca;
        tuxinghua x;
        //char infix[N];
        //    getc a;
        int z=0;
        
        
        
        while(1){
            x.shengcheng(infix);
            printf("%s=\n",infix);
            ca.work(infix);
        //    x.tgetchars(infix);
    //    gets(infix);
            scanf("%s",&infix);
            //    printf("%s=\n",infix);
        //    ca.work(infix);
            ca.getanswer(infix);
        //        z++;
        }
        
        
    }
    View Code

    本次实验我感悟最深的是项目设计前的规范性。

    因为第一次个人项目时没有一个详细的规划,所以在将其模块化时遇到了很大的困难。因此不得不对于整体结构进行了一定的调整。

    即便如此,在与生成控制函数耦合的时候,也不得不将一些接口变成了全局变量,来减少代码的改变量。这极大的降低了代码模块化之后的通用性。

    同时,因为在完成mfc界面前没有一个详细的规划,所以也遇到了很大的困难。

    除此之外,也感到了沟通的重要性,因为在代码编写的过程中,没能提前统一代码的规范和结构,结果在开始编写后遇到了很多问题,让进度不快反慢,有一种“单干反而更轻松”的想法。

  • 相关阅读:
    华为交换机LACP模式(动态)链路聚合配置示例
    H3C交换机配置链路聚合
    ODBC数据源的作用及配置
    SQL Server Management Studio与SQL Server Configuration Manager
    SQL Server 2008 允许远程连接的解决方法
    多实例并存的技术限制,与原因
    多个SQL server实例
    SQL Server实例
    Oracle
    Burp Suite Professional更换闪退日记
  • 原文地址:https://www.cnblogs.com/13070036dj/p/5398380.html
Copyright © 2020-2023  润新知