zoukankan      html  css  js  c++  java
  • 结对项目总结

    经过3周的开发与测试工作,此次结对项目终于告一段落。

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

    在这次结对编程过程中,我们主要完成了以下几点:

    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++;
    }


    }

  • 相关阅读:
    截取中文字符加省略号
    全面解读PHP的Yii框架中的日志功能
    curl 异步捉取数据类
    微信企业号OAuth2.0验证接口来获取成员的身份信息
    Linux下修改Mysql的用户(root)的密码
    curl 抓取图片
    git获取一个版本相对于另一个版本新增,修改,删除的文件
    php打乱数组二维数组、多维数组
    js 解密 16进制转10进制,再取ascii码的对应值
    防止页面后退(使浏览器后退按钮失效)
  • 原文地址:https://www.cnblogs.com/ppppppp1995/p/5601248.html
Copyright © 2011-2022 走看看