小白菜的坑

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

作业要求:https://edu.cnblogs.com/campus/nenu/SWE2017FALL/homework/997

结对对象:任思佳

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

       2.支持括号

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

       4.支持分数出题和运算

我的实现:功能一、二、三

本博客主要包含以下五点:

    1.功能的重点难点及运行截图

    2.在编码、争论、复审等活动中花费时间较长,给我较大收获的五事件

    3.结对编程照片

    4.结对编程体会

    5.版本控制

一、功能的重点难点及运行截图

  • 功能一

重点生成随机数

使用方法:

#include <time.h>  //使用当前时钟做种子

char num[] = { '41','42','43','44','45' };

srand((unsigned)time(NULL));  //初始化随机数
        for (i = 0; i < 5; i++)  //产生随机数
        {
            n =   rand() % 5;   //取0到4的随机数
            nnum[i] = num[n];
        }

让时间当种子,这样srand每次返回的值就是不相同的。随机生成操作符用到的也是这个方法。由于后续方便随机数数组与操作符数组的结合,所以在此把随机数数组定义为char型,如41转换为字符为整型1。

重点两个数组结合,输出运算表达式

实现方法:

narr[0] = nnum[0];
narr[1] = opt[0];
narr[2] = nnum[1];
narr[3] = opt[1];
narr[4] = nnum[2];
narr[5] = opt[2];
narr[6] = nnum[3];
narr[7] = '\0';
printf("%-15s", narr);

可以输出简单的表达式,不含括号。

重点:不含括号的混合计算(这个方法简单粗暴,功能二中有改进)

实现方法:

       /*
        计算,先找到'*'或'/',然后再算'+'或'-',比较运算符优先级
        若第一个运算符为'*'或'/',不用特意判断第二个运算符
        若第一个运算符为'+'或'-',需判断第二个运算符,以此类推
        */
        if (opt[0] == '*' || opt[0] == '/')
        {
            if (opt[0] == '*')
            {
                r1 = num[0] * num[1];
                if (opt[1] == '*')
                {
                    r2 = r1 * num[2];
                    if (opt[2] == '*')
                        r3 = r2 * num[3];
                    else if (opt[2] == '/')
                        r3 = r2 / num[3];
                    else if (opt[2] == '+')
                        r3 = r2 + num[3];
                    else
                        r3 = r2 - num[3];
                }
                else if (opt[1] == '/')
                {
                    r2 = r1 / num[2];
                    if (opt[2] == '*')
                        r3 = r2 * num[3];
                    else if (opt[2] == '/')
                        r3 = r2 / num[3];
                    else if (opt[2] == '+')
                        r3 = r2 + num[3];
                    else
                        r3 = r2 - num[3];
                }
                else if (opt[1] == '+')
                {
                    if (opt[2] == '*')
                        r2 = num[2] * num[3];
                    else if (opt[2] == '/')
                        r2 = num[2] / num[3];
                    else if (opt[2] == '+')
                        r2 = num[2] + num[3];
                    else
                        r2 = num[2] - num[3];
                    r3 = r1 + r2;
                }
                else
                {
                    if (opt[2] == '*')
                    {
                        r2 = num[2] * num[3];
                        r3 = r1 - r2;
                    }
                    else if (opt[2] == '/')
                    {
                        r2 = num[2] / num[3];
                        r3 = r1 - r2;
                    }
                    else if (opt[2] == '+')
                    {
                        r2 = num[2] + num[3];
                        r3 = r1 - r2;
                    }
                    else
                        r3 = r1 - num[2] - num[3];
                }
            }

            if (opt[0] == '/')
            {
                r1 = num[0] / num[1];
                if (opt[1] == '*')
                {
                    r2 = r1 * num[2];
                    if (opt[2] == '*')
                        r3 = r2 * num[3];
                    else if (opt[2] == '/')
                        r3 = r2 / num[3];
                    else if (opt[2] == '+')
                        r3 = r2 + num[3];
                    else
                        r3 = r2 - num[3];
                }
                else if (opt[1] == '/')
                {
                    r2 = r1 / num[2];
                    if (opt[2] == '*')
                        r3 = r2 * num[3];
                    else if (opt[2] == '/')
                        r3 = r2 / num[3];
                    else if (opt[2] == '+')
                        r3 = r2 + num[3];
                    else
                        r3 = r2 - num[3];
                }
                else if (opt[1] == '+')
                {
                    if (opt[2] == '*')
                        r2 = num[2] * num[3];
                    else if (opt[2] == '/')
                        r2 = num[2] / num[3];
                    else if (opt[2] == '+')
                        r2 = num[2] + num[3];
                    else
                        r2 = num[2] - num[3];
                    r3 = r1 + r2;
                }
                else
                {
                    if (opt[2] == '*')
                        r2 = num[2] * num[3];
                    else if (opt[2] == '/')
                        r2 = num[2] / num[3];
                    else if (opt[2] == '+')
                        r2 = num[2] + num[3];
                    else
                        r2 = num[2] - num[3];
                    r3 = r1 - r2;
                }
            }
        }
        //第一个运算符为'+'或'-',需判断第二个运算符
        if (opt[0] == '+' || opt[0] == '-')
        {
            if (opt[0] == '+')
            {
                if (opt[1] == '*')
                {
                    r1 = num[1] * num[2];
                    if (opt[2] == '*')
                        r2 = r1 * num[3];
                    else if (opt[2] == '/')
                        r2 = r1 / num[3];
                    else if (opt[2] == '+')
                        r2 = r1 + num[3];
                    else
                        r2 = r1 - num[3];
                    r3 = r2 + num[0];
                }
                else if (opt[1] == '/')
                {
                    r1 = num[1] / num[2];
                    if (opt[2] == '*')
                        r2 = r1 * num[3];
                    else if (opt[2] == '/')
                        r2 = r1 / num[3];
                    else if (opt[2] == '+')
                        r2 = r1 + num[3];
                    else
                        r2 = r1 - num[3];
                    r3 = r2 + num[0];
                }
                else if (opt[1] == '+')
                {
                    if (opt[2] == '*')
                    {
                        r1 = num[2] * num[3];
                        r3 = r1 + num[0] + num[1];
                    }
                    else if (opt[2] == '/')
                    {
                        r1 = num[2] / num[3];
                        r3 = r1 + num[0] + num[1];
                    }
                    else if (opt[2] == '+')
                        r3 = num[0] + num[1] + num[2] + num[3];
                    else
                        r3 = num[0] + num[1] + num[2] - num[3];
                }
                else
                {
                    if (opt[2] == '*')
                    {
                        r1 = num[2] * num[3];
                        r3 = num[0] + num[1] - r1;
                    }
                    else if (opt[2] == '/')
                    {
                        r1 = num[2] / num[3];
                        r3 = num[0] + num[1] - r1;
                    }
                    else if (opt[2] == '+')
                        r3 = num[0] + num[1] - num[2] + num[3];
                    else
                        r3 = num[0] + num[1] - num[2] - num[3];
                }
            }
            if (opt[0] == '-')
            {
                if (opt[1] == '*')
                {
                    r1 = num[1] * num[2];
                    if (opt[2] == '*')
                        r3 = num[0] - r1 * num[3];
                    else if (opt[2] == '/')
                        r3 = num[0] - r1 / num[3];
                    else if (opt[2] == '+')
                        r2 = num[0] - r1 + num[3];
                    else
                        r3 = num[0] - r1 - num[3];
                }
                else if (opt[1] == '/')
                {
                    r1 = num[1] / num[2];
                    if (opt[2] == '*')
                        r2 = r1 * num[3];
                    else if (opt[2] == '/')
                        r2 = r1 / num[3];
                    else if (opt[2] == '+')
                        r2 = r1 + num[3];
                    else
                        r2 = r1 - num[3];
                    r3 = num[0] - r2;
                }
                else if (opt[1] == '+')
                {
                    if (opt[2] == '*')
                    {
                        r1 = num[2] * num[3];
                        r3 = num[0] - num[1] + r1;
                    }
                    else if (opt[2] == '/')
                    {
                        r1 = num[2] / num[3];
                        r3 = num[0] - num[1] + r1;
                    }
                    else if (opt[2] == '+')
                        r3 = num[0] - num[1] + num[2] + num[3];
                    else
                        r3 = num[0] - num[1] + num[2] - num[3];
                }
                else
                {
                    if (opt[2] == '*')
                    {
                        r1 = num[2] * num[3];
                        r3 = num[0] - num[1] - r1;
                    }
                    else if (opt[2] == '/')
                    {
                        r1 = num[2] / num[3];
                        r3 = num[0] - num[1] - r1;
                    }
                    else if (opt[2] == '+')
                        r3 = num[0] - num[1] - num[2] + num[3];
                    else
                        r3 = num[0] - num[1] - num[2] - num[3];
                }
            }
        }              
View Code

运行截图:

   

  • 功能二

 重点:添加括号

实现方法:

//生成带括号或不带括号的表达式
        if (((opt[0] == '*' || opt[0] == '/') && (opt[1] == '+' || opt[1] == '-')) || ((opt[2] == '*' || opt[2] == '/') && (opt[1] == '+' || opt[1] == '-')))
        {
            n = rand() % 2;
            if (n % 2 == 0)
            {
                narr[0] = nnum[0];
                narr[1] = opt[0];
                narr[2] = '(';
                narr[3] = nnum[1];
                narr[4] = opt[1];
                narr[5] = nnum[2];
                narr[6] = ')';
                narr[7] = opt[2];
                narr[8] = nnum[3];
                narr[9] = '\0';
                printf("%-15s", narr);
                inFix2PostFix(narr, postFix);
                result = postFixEval(postFix);
                //printf("%d", result);
                if (result - ((int)result) == 0)  //若小数点后数字全为0,则输出为整型
                    printf("%d", (int)result);
                else
                    printf("%.2f", result);
            }
            else
            {
                narr[0] = nnum[0];
                narr[1] = opt[0];
                narr[2] = nnum[1];
                narr[3] = opt[1];
                narr[4] = nnum[2];
                narr[5] = opt[2];
                narr[6] = nnum[3];
                narr[7] = '\0';
                printf("%-15s", narr);
                inFix2PostFix(narr, postFix);
                result = postFixEval(postFix);
                //printf("%d", result);
                if (result - ((int)result) == 0)
                    printf("%d", (int)result);
                else
                    printf("%.2f", result);
            }
        }
View Code

我没有想到随机实现括号位置的固定,所以对于括号的出现位置,我选择固定,然后产生一个随机数,若这个数为偶数,括号出现,反之没有括号。代码里还有三个循环体没有贴出。

重点:

实现方法:

//判断字符是否为操作符
bool IsOperator(char c)
{
    char op[] = { '+', '-', '*', '/', '(', ')' };//操作符数组 
    for (int i = 0; i < sizeof(op); i++) 
    { 
        if (c == op[i]) 
            return true; 
    } 
    return false; 
}
// 比较两个操作符的优先级
int ComPriority(char op1, char op2)
{
    if (op1 == '(')
    {
        return -1;
    }

    if (op1 == '+' || op1 == '-')
    {
        if (op2 == '*' || op2 == '/')
        {
            return -1;
        }
        else
        {
            return 0;
        }
    }

    if (op1 == '*' || op1 == '/')
    {
        if (op2 == '+' || op2 == '-')
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}
View Code

遇到数字压栈,遇到第二个操作符先和第一个操作符比较,然后计算结果压栈。

难点:逆波兰式(后缀表达式)

实现方法

// 中缀表达式转换成后缀表达式
void inFix2PostFix(char* inFix, char* postFix)
{
    int j = 0, len;
    char c;
    stack<char> st;

    len = strlen(inFix);

    for (int i = 0; i < len; i++)
    {
        c = inFix[i];

        if (c == '(')
            st.push(c);
        else if (c == ')')
        {
            while (st.top() != '(')
            {
                postFix[j++] = st.top();
                st.pop();
            }
            st.pop();
        }
        else
        {
            if (!IsOperator(c))
                st.push(c);
            else
            {
                while (st.empty() == false && ComPriority(st.top(), c) >= 0) 
                {
                    postFix[j++] = st.top();
                    st.pop();
                }
                st.push(c);
            }
        }
    }

    while (st.empty() == false)
    {
        postFix[j++] = st.top();
        st.pop();
    }
    postFix[j] = 0;
}
View Code

运行截图:

  •  功能三

重点:又控制台输入题目数

实现方法:

int a = atoi(argv[2]);  

二、在编码、争论、复审等活动中花费时间较长,给我较大收获的五事件

a 首先是使用什么语言,最后统一选择了两人都熟悉的c语言;

b 然后是制定代码规范过程中对于规范的条例有过观点不和,最后统一修正形成一套规范;

c 对于要使用的编程工具,我想要使用codeblocks,而她想要使用VS,也产生了一些分歧;

d 然后在编码过程中对于如何判断运算符号优先级,有过关于不同方法的争论,我曾经做过下图这样的尝试:最后还是达成了一致,使用了前文提到的方法;

e 在进行单元测试时,对于工具选择也有分歧,关于应该使用cunit,还是cppunit,单元测试环节耗费了大量的时间,安装工具并修改各种配置,步骤很繁琐,印象深刻。

三、结对编程照片

四、结对编程体会

结对编程是一个互相学习的过程。在结对编程的过程中,我们会不断进行讨论,两个人的想法能够进行互补,对于提高自己解决问题和编程能力有很大的帮助。与我们俩各自独立完成相比,结对编程能编写出质量更高的代码。

五、版本控制

git地址:https://git.coding.net/a284617374/f4.git

posted on 2017-10-11 16:00  小白菜的坑  阅读(125)  评论(0编辑  收藏  举报