• 四则运算实现


    这次和代秋彤同学结对编写四则运算这一题目,之前从来没有和别人结对编程过,感觉也挺有趣的。综合了两个人的编程能力等各方面因素,选择了用c语言来完成。

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

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

    #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];
            }

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

    实现方法:

    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] = '';
    printf("%-15s", narr);

    部分代码:

    功能1:

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

    功能1运行结果:

    功能2的重点和难点是判断运算符号的优先级吧,特别是功能2的括号,挺难插的。受到一个博客的启发,使用将中缀表达式转换成后缀表达式,再对后缀表达式求值的方法。使用这种方法是因为:1.中缀表达式必然存在后缀表达式  2.后缀表达式不存在优先级问题,只需利用栈进行“从左至右依次计算”即可。后缀表达式的计算方法,就是:将后缀表达式从左到右依次遍历,如果当前元素为数字则入(操作数)栈,如果为操作符,则pop出栈顶两个元素(第一次pop出的是右操作数,第二次pop出的是左操作数)进行运算,然后将计算结果再次入栈,直至表达式结束,此时操作数栈内理应只剩一个元素即表达式结果。

    博客链接

    https://m.baidu.com/from=1099a/bd_page_type=1/ssid=0/uid=0/baiduid=2E9E94CE90CDF152A3864C487187C1BF/w=0_10_/t=zbios/l=3/tc?ref=www_zbios&pu=sz%401320_480%2Ccuid%4037CEBE839C969F533079BBFDAC81C03FF40701A80FCACINTEAI%2Ccua%40750_1334_iphone_9.3.0.11_0%2Ccut%40iPhone9%252C1_10.3.3%2Cosname%40baiduboxapp%2Cctv%401%2Ccfrom%401099a%2Ccsrc%40bdbox_tserch_txt%2Ccud%40MTNBMTc2QjEtNzkzMi00RjdGLTg3QTUtMTM0MzlDRTk1M0FF%2Cta%40zbios_1_10.3_6_9.3%2Cusm%401%2Cvmgdb%400020100228y&lid=11659372937234508980&order=6&fm=alop&tj=www_normal_6_0_10_title&vit=osres&m=8&srd=1&cltj=cloud_title&asres=1&title=...%E7%BB%93%E6%9E%84C%E8%AF%AD%E8%A8%80%E7%89%88(8)%E5%90%8E%E7%BC%80%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%A0%88%E4%B8%8E%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97%E8%AE%A1%E7%AE%97%E5%99%A8&dict=30&w_qd=IlPT2AEptyoA_yi7pA6koujMOVIEt-J_oy-asAWhaeZ3GgBEAzsep-eR-wc8&sec=24518&di=d3d59b58d648f9be&bdenc=1&tch=124.1250.346.1383.4.437824&nsrc=IlPT2AEptyoA_yixCFOxXnANedT62v3IEQGG_ytK1DK6mlrte4viZQRAXzqmAzrIBVWwdoTMth5DwHycAT-il17&eqid=a1ce69e993aa70001000000359d8e5b9&wd=&clk_info=%7B%22srcid%22%3A%221599%22%2C%22tplname%22%3A%22www_normal%22%2C%22t%22%3A1507386822106%2C%22sig%22%3A%2212162%22%2C%22xpath%22%3A%22div-a-h3%22%7D&sfOpen=1&from=singlemessage&isappinstalled=0

    功能2:

    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;
            }
        }
    }
     
    // 中缀表达式转换成后缀表达式
    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;
    }
    
    //后缀表达式求值
    double postFixEval(char* postFix)
    {
        stack<char> st;
        int len = strlen(postFix);
        char c;
    
        for (int i = 0; i < len; i++)
        {
            c = postFix[i];
            if (IsOperator(c) == false)
            {
                st.push(c - '0');
            }
            else
            {
                char op1, op2;
                int val;
    
                op1 = st.top();
                st.pop();
                op2 = st.top();
                st.pop();
    
                switch (c)
                {
                case '+':
                    val = op1 + op2;
                    break;
                case '-':
                    val = op2 - op1;
                    break;
                case '*':
                    val = op1 * op2;
                    break;
                case '/':
                    val = op2 / op1;
                    break;
                }
                st.push(val);
            }
        }
    
        return st.top();
    }

     

    功能2运行结果:

    功能3的重点和难点是命令行参数,支持手动输入题目数量:

    部分代码:

    功能3:

    int main(int argc, char *argv[])
    {
        int y;
        int rcount = 0; //rcount答对题目计数
        int a = atoi(argv[2]);  //传入的参数转成整数
    
        if (!(a == 1 || a == 2 || a == 3 || a == 4 || a == 5 || a == 6 || a == 7 || a == 8 || a == 9 || a == 10 || a == 11 || a == 12 || a == 13 || a == 14 || a == 15 || a == 16 || a == 17 || a == 18 || a == 19 || a == 20))
        {
            printf("题目数量必须是 正整数。");
            exit(0);
        }
    
        for (y = 0; y < a; y++)
        {
            int i, j, n, op;
            float answer, result;
            char num[] = { '41','42','43','44','45' };
            char operate[] = { '+', '-', '*', '/' }, opt[3];
            char narr[] = { 0 };
            char nnum[4];
            char postFix[20];
            //double answer;
    
            srand((unsigned)time(NULL));  //初始化随机数
            for (i = 0; i < 4; i++)  //产生随机数
            {
                n =   rand() % 5;   //取0到4的随机数
                nnum[i] = num[n];
            }
            srand((unsigned)time(NULL));
            for (j = 0; j < 4; j++)  //从给定的四个运算符中随机产生三个相同或不同的运算符
            {
                op = rand() % 4;
                opt[j] = operate[op];
            }
    
            //生成带括号或不带括号的表达式
            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] = '';
                    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] = '';
                    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);
                }
            }
            else if (opt[0] == '+' && (opt[1] == '*' || opt[1] == '/'))
            {
                narr[0] = '(';
                narr[1] = nnum[0];
                narr[2] = opt[0];
                narr[3] = nnum[1];
                narr[4] = ')';
                narr[5] = opt[1];
                narr[6] = nnum[2];
                narr[7] = opt[2];
                narr[8] = nnum[3];
                narr[9] = '';
                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);
    
            }
            else if ((opt[0] == '/'&&opt[1] == '-') || (opt[0] == '*'&&opt[1] == '+'))
            {
                narr[0] = '(';
                narr[1] = '(';
                narr[2] = nnum[0];
                narr[3] = opt[0];
                narr[4] = nnum[1];
                narr[5] = ')';
                narr[6] = opt[1];
                narr[7] = nnum[2];
                narr[8] = ')';
                narr[9] = opt[2];
                narr[10] = nnum[3];
                narr[11] = '';
                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);
            }
            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] = '';
                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);
            }
            printf("
    ");
            //printf("?");
            int ntime;
            ntime = 1000 + rand() % 1000;
            Sleep(ntime);

    功能3运行结果:

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

    编程收获就是学到了很多新技能吧,对c语言有新的认识,可以说是一次巩固和发展的过程,编程过程中使用的知识点,好多都在书上读到过,在课堂上学习过,然而真的到了实际应用的时候,或者想不到使用,或者不知道如何具体应用,没有动手的经历,书本上的知识永远不能变成自己的,基础和实践同样重要。还有交到了新朋友,附上某一次的工作照:

    结对编程的体会 就是两个人一起工作要比一个人轻松,有效率,而且集思广益,在解决问题时会得到更好的解决方案。在此感谢代秋彤同学对我的帮助,受益匪浅。

    争执的点 

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

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

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

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

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

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

  • 相关阅读:
    .net程序员书单
    脱敏小软件
    .NET处理HTTP请求
    WPF 按名称查找控件
    软件工程现行国标汇集
    企业应用架构模式读书笔记 第一章 分层
    mysql远程访问
    知道二叉树的先序和中序遍历,重建该二叉树
    微信小程序地图模块
    微信小程序蓝牙模块
  • 原文地址:https://www.cnblogs.com/rensijia/p/7643281.html
Copyright © 2020-2023  润新知