zoukankan      html  css  js  c++  java
  • 四则运算表达的达成

    需求分析

    此次四则运算的要求如下:

    1.由txt文档中逐行导入算式,算式中实型用分数形式表示。

    2.算式中应涵盖加减乘除括号,真假分数,以及长度大于10的超长算式。

    3.判断用户输入算式的值是否正确,如正确则提示,错误则显示正确答案。

    程序设计

    将四则运算的求解拆分成如下问题:

    1、读入中缀表达式算式

    2、中缀表达式转后缀

    3、后缀表达式求值

    4、对结果进行化简

    5、输入答案并对比

    程序实现

    前三步在上学期数据结构课程中已经完成,此处只大概说明原理

    1、读入中缀表达式算式

    从txt分行读取数据,因为每次计算都是一行,所以在循环中文件不关闭,循环结束才关闭。

    int getchars()
    {
    
    // VC++6.0
        if(NULL == fp)
        {
            printf("failed to open dos.txt\n");
            return 0;
        }
    
     if(!feof(fp))
        {
            memset(infix, 0, sizeof(infix));
            fscanf(fp,"%s",infix); // 包含了\n
            printf("\n%s\n", infix);        
            return 1;
        }

    在此处进行预处理,将多位数字和各位数字区分,防止产生歧义

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

    2、中缀表达式转后缀

    根据符号不同,进行不同的压栈和出栈操作,得出后缀表达式

    3、后缀表达式求值

    从栈中取字符,根据取出符号的不同,将取出的数进行相应的运算再入栈保存

    在此步骤中考虑到本次程序要求结果保存成为分数,而上学期则没有要求,所以应当对数据的格式进行修改。建立结构体以方便记录数字的分子和分母。

    struct fra{
        char str[10];//为了在栈中记录符号,所以包括数字全部用char记录
        double up;//分子
        double down;//分母
    };

    这样在计算结果时,读到同样的符号时,只需要改变计算的方法,就可以在程序不需要大的改动的前提下,增加分数,如下改动:

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

    4、对结果进行化简

    int gcd(int a,int b) {          //最大公约数
        if(b == 0)
            return a;
        else
            return gcd(b,a % b);
    }

    求出答案分子、分母的最大公约数并分别用分子、分母除以该数。

    5、输入答案并对比

    不一样则输出正确答案并记错误一次。

    测试程序

    程序问题

    随机生成算式较为复杂,我原本想要随机生成一个奇数数字作为字符串长度,在按照数字..符号..数字..符号..数字这样的顺序逐次生成算式。但是因为括号难以达成随机化,所以未能完成。

    而且在验证答案时我选择的是将输入的答案,作为字符串,通过程序进行处理,再次进行计算,并把生成的答案存在一个结构体内,与原有的结构体答案进行对比。以此来判断对错,这样必然使程序的预算量变大。

    除此之外图形化界面也没有制作。

  • 相关阅读:
    C#进阶系列——WebApi 路由机制剖析:你准备好了吗?
    Socket长连接和短连接的区别
    C#socket通信时,怎样判断socket双方是否断开连接
    Redis常见面试题
    [C# 线程处理系列]专题三:线程池中的I/O线程
    结对编程第一次作业
    软件工程第三次作业
    软件工程第二次作业
    人生中的第一篇博客
    CPU 分类
  • 原文地址:https://www.cnblogs.com/13070036dj/p/5296295.html
Copyright © 2011-2022 走看看