2017年软件工程第四次作业-3四则运算

one

要求1 参考《构建之法》第4章两人合作,结对编程上述功能,要求每人发布随笔1篇 (代码是共同完成的,博客是分别完成的)。 (1) 给出每个功能的重点、难点、编程收获。(2)给出结对编程的体会,以及 (3) 至少5项在编码、争论、复审等活动中花费时间较长,给你较大收获的事件。

   (1).给出每个功能的重点、难点、编程收获

      功能一的重点难点我感觉是随机数的产生以正确算数。

      功能二的重点难点是后波兰表达式、堆栈的实现。

      功能三的重点难点是限定题目数量,避免重复打印,还要工整输出。

      功能四的重点难点是分数参与运算,得到女神青睐。

      我的编程收获是:首先看见四则运算就要想起来用栈来实现,分别有两个栈,算数栈和算符栈。然后如何去读取。其次就是涉及到四则运算就一定要用到运算符,运算符是有优先级的,就要想办法对算符优先级进行比较,再决定哪个运算符进栈哪个运算符直接参与运算。最后就是逆波兰表达式和堆栈问题,虽然此处我没有写出来,参考了别人的代码,但是我对这个知识点也有了更省的了解。这就是我这次编程的收获。

 (2).结对编程的体会:

         首先我在结对编程之前先读了《构建之法》第四章两人合作这一部分知识,让我更好的理解了结对编程的意义。邹欣老师说,在结对编程中,任何一段代码都至少被两双眼睛看过,被两个脑袋思考过,结对编程避免了“我的代码”还是“他的代码”的问题,使而整个代码的责任不属于某个人,而是属于两个人,进而属于整个团队。还有结对编程中驾驶员和领航员的角色要经常互换,避免长时间紧张工作而导致的观察力和判断力下降。所以我认为结对编程还是很有必要的,对于一个好性能的软件或者程序,我感觉结对编程是不可缺少的。

      和我结对编程的是黄泽宇同学,我们两个互相监督完成了这次的作业。虽然说有些代码是我们两个从别人那里参考过来的,但是我们也是一起对代码进行理解。谢谢黄泽宇同学对我提出的疑问耐心解答,对我不会的知识点进行讲解,也因为黄泽宇同学的帮助和指导,我们的程序才会更好的运行出来。

(3).至少5项在编码、争论、复审等活动中花费时间较长,给你较大收获的事件

      功能一的实现我们两个花费了不少时间,因为功能一相对于其他功能是比较基础的一个功能,我们在编码中就用了不少时间,基本功能总是实现不了,我们两个就开始百度或者查阅资料,比如在数据结构课本中再研究用栈来完成四则运算,是怎么读取算数和算符,栈指针如何进行操作,让我有较大的收获。在功能二中逆波兰表达式中也花费了不少时间,因为这个功能我们两个实现不了,但是也挣扎过,查资料百度,然后试着理解编写,但是也以失败告终,最后还是用了大量时间从别人代码里参考出来再用在自己的代码里,使其功能能运行出来。其中我们两个在限定题目数量和给出出题范围中也花费了不少时间,功能一直实现不了,我们还是边讨论别查资料,总之道路还是很坎坷的哈哈。最后在代码复审中,还是没有完成老师规定的输出格式,也花费不少时间来进行代码规范,代码规范应该是没有问题的,我和黄泽宇会继续努力的完善代码。

要求2 给出照片1张,包括结对的2位同学、工作地点、计算机,可选项包括其他能表达结对编程工作经历的物品或场景。

        下面是我和黄泽宇同学一起结对编程的照片:

two

功能1. 四则运算 ,支持出题4个数的四则运算题目,所有题目要求作者有能力正确回答

(提示:1/3 != 0.33333333333333333333333333333333,而是无限长)。

     功能1运行截图:

功能2. 支持括号

功能3. 限定题目数量,"精美"打印输出,避免重复

功能4. 支持分数出题和运算

功能2要求支持括号,我写不出来逆波兰式算法,我和黄泽宇从网上扒下来用在自己程序里了。

运行截图如下:

three

    四则运算的实现需要用到栈来实现,运算式求值的核心思想:将运算式逐字符读取,在这个读取的过程中首先要先判断是算符还是算数,如果是算符的话,就与算符栈站定元素进行优先级比较,如果优先级高,则进栈,否则就进行运算,如果是算数,则入算数栈。

 1. 本程序用了两个栈,分一个为char类型存储运算符,一个为float类型存储算数。定义了四个栈指针分别是 

                                                 SC *Push(SC *s, char c);  //使算符c进入算符栈

                                                 SF *Push(SF *s, float f) ; //使算数f进入算数栈

                                                 SC *Pop(SC *s);              //使算符栈的栈顶元素出栈

                                                 SF *Pop(SF *s) ;              //使算数栈的栈顶元素出栈

 

代码如下:

 

 

SC *Push(SC *s, char c)         
{
     SC *p = (SC*)malloc(sizeof(SC));
     p->c = c;
     p->next = s;
     return p;
}
SF *Push(SF *s, float f)      
{
     SF *p = (SF*)malloc(sizeof(SF));
     p->f = f;
     p->next = s;
     return p;
}
SC *Pop(SC *s) 
{
    SC *q = s;
    s = s->next;
    free(q);
    return s;
}
SF *Pop(SF *s)  
{
    SF *q = s;
    s = s->next;
    free(q);
    return s;
}

2.对算数运算符的操作。

a.首先列出优先级关系,运算符支持+ - * /,#为结束符。

             +    -    *    /    (     )     #     
       +    >    >   <   <   <   >     >
       -     >    >   <   <   <   >     >
       '     >    >    >   >   <   >    >
       /     >    >    >   >   <   >    >
       (    <    <    <   <    <   =
       )    >    >    >   >         >    >
      #    <    <    <   <    <         =

 

unsigned char Prior[7][7] =
{ 
        
        '>', '>', '<', '<', '<', '>', '>',
            '>', '>', '<', '<', '<', '>', '>',
        '>', '>', '>', '>', '<', '>', '>',
        '>', '>', '>', '>', '<', '>', '>',
        '<', '<', '<', '<', '<', '=', ' ',
        '>', '>', '>', '>', ' ', '>', '>',
        '<', '<', '<', '<', '<', ' ', '=',
         };

b.判断是不是运算符, 判断Test字符是否在运算符集里,返回是或者不是。

Status In(char Test, char *TestOp)
{
   int Find = false;
   for (int i = 0; i< OPSETSIZE; i++)
    {
        if (Test == TestOp[i])
            Find = true;
    }
    return Find;
}

c.判断哪个是运算符,返回运算符在运算符集里的位置.

Status ReturnOpOrd(char op, char *TestOp)
{
    for (int i = 0; i< OPSETSIZE; i++)
    {
         if (op == TestOp[i])
             return i;
    }
}

d.判断两个算符的优先级,返回><=

char precede(char Aop, char Bop)
{
    return Prior[ReturnOpOrd(Aop, OPSET)][ReturnOpOrd(Bop, OPSET)];
}

3,求解运算式。 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。  

float EvaluateExpression(char* MyExpression)
{ 
    SC *OPTR = NULL;        
    SF *OPND = NULL;       
    char TempData[20];
    float Data, a, b;
    char theta, *c, Dr[] = { '#', '\0' };
    OPTR = Push(OPTR, '#');
    c = strcat(MyExpression, Dr);
    strcpy(TempData, "\0");   
    while (*c != '#' || OPTR->c != '#')
    {
        if (!In(*c, OPSET))
        {
             Dr[0] = *c;
             strcat(TempData, Dr);             
             c++;
             if (In(*c, OPSET))
             {
                 Data = atof(TempData);          
                 OPND = Push(OPND, Data);
                 strcpy(TempData, "\0");
             }
         }
       else     
         {
             switch (precede(OPTR->c, *c))
             {
             case '<':   
                 OPTR = Push(OPTR, *c);
                 c++;
                break;
             case '=':   
                 OPTR = Pop(OPTR);
                 c++;
                 break;
             case '>':  
                 theta = OPTR->c; OPTR = Pop(OPTR);
                 b = OPND->f; OPND = Pop(OPND);
                 a = OPND->f; OPND = Pop(OPND);
                 OPND = Push(OPND, Operate(a, theta, b));
                 break;
             } //switch  
       }
     } //while   
     return OPND->f;
}

4.主函数。

int main()
{
    srand((int)time(NULL));  
    int num1, num2, num3, num4, count, n, change, amount, shuchu, range, j, repeat = 0, bracket, proper_fs, right = 0, wrong = 0;
    string str_num1, str_num2, temp;
    float Answer, InputAns;
    cout << "Let's do the math. Be sure to follow the requirements. Come on!" << endl;
    cout << "All right, are you ready?" << endl;
    cout << "Is there a multiplication and division?1:YES,0:NO:" << endl;
    cin >> n;
    cout << "Are there parentheses?1:YES,0:NO:" << endl;
    cin >> bracket;
    cout << "Is there a proper fraction?1:YES,0:NO:" << endl;
    cin >> proper_fs;
    cout << "Please enter a numeric range:" << endl;
    cin >> range;
    cout << "Please enter the number of questions:" << endl;
    cin >> amount;
    string Equation[1000];
    char symbol;
    cout << "OK, let's get started:" << endl;
    for (int i = 0; i<amount; i++)
    {
        //count = random() % 3 + 2;
        count = 4;
        str_num1 = create_num(proper_fs, range);
        str_num2 = create_num(proper_fs, range);
        symbol = create_symbol(n);
        Equation[i] = combination(str_num1, str_num2, symbol);
        if (count>2)
        {
            for (count; count > 2; count--)
            {
                symbol = create_symbol(n);
                str_num1 = Equation[i];
                if (bracket == 1)
                {
                    change = random() % 3;
                    if (change == 0)
                    {
                        str_num1 = '(' + str_num1 + ')';
                    }
                }
                symbol = create_symbol(n);
                str_num2 = create_num(proper_fs, range);
                change = random() % 2;
                if (change == 0)
                {
                    temp = str_num1;
                    str_num1 = str_num2;
                    str_num2 = temp;
                }
                Equation[i] = combination(str_num1, str_num2, symbol);
            }
        }
        for (j = 0; j < i; j++)
        {
            if (Equation[j] == Equation[i])
            {
                i = i - 1;
                repeat = 1;
                break;
            }
        }
        if (repeat != 1)
        {
            cout << Equation[i] << "=";
            cin >> InputAns;
            Answer = get_ans(Equation[i]);
            Answer *= 100;
            int temp = (int)Answer;
            Answer = ((double)temp) / 100.00;
            if (InputAns == Answer)
            {
                cout << "Correct answer!";
                right++;
            }
            else
            {
                cout << "Wrong answer!The correct answer is:";
                cout << setprecision(2) << fixed << Answer;
                wrong++;
            }
            cout << endl;
        }
    }
    cout << "You answer the correct number is " << right << ",You answer the wrong number is " << wrong << endl <<endl;
    system("pause");

}


four

要求3 使用coding.net做版本控制。checkin 前要求清理 临时文件、可执行程序,通常执行 build-clean可以达到效果

版本控制:

https://coding.net/u/MingZi-/p/f4-/git/tree/master

 

 

 

                                      

 

 

 

     

 

转载于:https://www.cnblogs.com/Mingezi/p/7643708.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值