zoukankan      html  css  js  c++  java
  • 辅助判卷程序阶段性成果

    目前已经大概完成程序的基础功能开发,实现功能为,读取txt文档中的题目,并显示在屏幕上,获取用户输入后,可根据电脑计算结果,判断对错,其中包括小数和分数两种形式。

    自己定义了三个类,如下:

    class unit
    {
    public:
        char op;
        double num;
        int kind;
        unit(){
            kind=0;
        }
        void set(char c){
            op=c;
            kind=1;
        }
        void set(double d){
            num=d;
            kind=2;
        }
    };

    后缀表达式的辅助存储结构,可同时存储数字与操作符。

    class fenshu
    {
    public:
        int fz;
        int fm;
        fenshu(int a,int b){
            fz=a;fm=b;
            yuefen();
        }
        void yuefen(){
            int t;
            int a=fz;
            int b=fm;
            if (a < b) {
                t = a;
                a = b;
                b = t;
            }
            while (t = a % b) {
                a = b;
                b = t;
            }
            if(b!=1){
                fz/=b;
                fm/=b;
            }
        }
        void print(){
            cout<<fz<<"/"<<fm;
        }
        fenshu operator +(fenshu &fs){
            fenshu f(fz*fs.fm+fs.fz*fm,fm*fs.fm);
            f.yuefen();
            return f;
        }
        fenshu operator -(fenshu &fs){
            fenshu f(fz*fs.fm-fs.fz*fm,fm*fs.fm);
            f.yuefen();
            return f;
        }
        fenshu operator *(fenshu &fs){
            fenshu f(fz*fs.fz,fs.fm*fm);
            f.yuefen();
            return f;
        }
        fenshu operator /(fenshu &fs){
            fenshu f(fz*fs.fm,fm*fs.fz);
            f.yuefen();
            return f;
        }
        void operator =(fenshu &fs){
            fz=fs.fz;
            fm=fs.fm;
        }
        bool operator ==(fenshu &fs){
            return fz==fs.fz&&fm==fs.fm;
        }
    };

    分数类,定义了一系列关于分数的运算显示。

    class Calculator
    {
    public:
        double result;                    //计算结果 
        fenshu fresult;                    //分数计算结果 
         bool error;                        //计算过程中是否有错误 
         string str;                        //存放中缀表达式 
        Calculator(string s):fresult(1,1){            //计算器初始化 
            clear();
            str=s;
        }
        int run(){                        //计算表达式的值,存入result 
            if(zzh(str)==-1){
                error=true;
                result=-1;
                return -1;
            }
            if(getResult()==-1){
                error=true;
                result=-1;
                return -1;
            }
            
            int i;
            bool b=true;
            for(i=0;i<str.size();i++){    //没有小数点,就计算分数结果 
                if(str[i]=='.'){
                    b=false;
                    break;
                }
                
            } 
            if(b){
                if(getFResult()==-1){
                    error=true;
                    fenshu f(-1,-1);
                    fresult=f;
                    return -1;
                }
            }
            return 0;
        }
        void clear(){                    //清空计算器 
            num=0;
            error=false;
            result=0;
        }
        void recalculator(string s){    //重启计算器对象 
            clear();
            str=s;
        }    
        void printfanswer(){
            int i=0;
            for(;i<str.size();i++){
                if(str[i]=='.'){
                    cout<<"答案为:"<<result<<endl;
                    return; 
                }
            }
            cout<<"答案为:";//<<result<<" 或 ";
            if(fresult.fm!=1)
                fresult.print();
            else
                cout<<fresult.fz;
            cout<<endl;
        }
    private:
        unit u[80];                        //存储后缀表达式 
         int num;                        //数量 
        int zzh(string s){                        //中缀表达式转后缀表达式 
            char c; 
            char temp1[80];
            double temp;
            string stemp;
            stack<char> st;
            while(!s.empty()){                    //如果字符串不为空则继续循环 
                c=s[0];
                if(isoperator(c)){                //是操作符 
                    s.erase(0,1);                //从string中删除操作符 
                    if(pushintostack(c,&st)==-1)            //处理当前操作符 
                        return -1;                //出错处理 
                }
                else{                            //是数字 
                    stringstream sst(s);
                    sst>>temp;
                    sprintf(temp1,"%g",temp);
                    stemp=temp1;
                    s.erase(0,stemp.size());    //从string中删除数字
                    sst.clear(); 
                    u[num++].set(temp);            //存储数字到栈中 
                }
            }
            if(pushintostack('#',&st)==-1)                //字符串处理完毕,输出所有栈中剩余操作符 
                return -1;
            return 0;
        }
        bool isoperator(char c){                //判断是否是操作符 
            if(c=='+')
                return true; 
            if(c=='-')
                return true; 
            if(c=='*')
                return true; 
            if(c=='/')
                return true; 
            if(c=='(')
                return true; 
            if(c==')')
                return true;     
            return false;
        }
        int youxian(char c1,char c2){            //判断两操作符优先级 
            if(c2=='#')        //结束符 
                return 0;
            if(c2=='(')
                return 1;
            if(c2==')')
                if(c1=='(')
                    return 2;
                else
                    return 0;
            if(c1=='(')
                if(c2=='+'||c2=='-'||c2=='*'||c2=='/')
                    return 1;
            if(c1=='*'||c1=='/')
                return 0;
            if(c1=='+'||c1=='-')
                if(c2=='*'||c2=='/')
                    return 1;
                else if(c2=='+'||c2=='-')
                    return 0; 
            return -1;
        }
        int pushintostack(char c,stack<char> *st){        //将操作符执行一系列入栈判断操作 
            char a;
            int y=0;
            while(!st->empty()){
                a=st->top();
                y=youxian(a,c);
                if(y==0){                //后来的操作符优先级小 
                    st->pop();
                    u[num++].set(a);
                }
                else if(y==1){            //后来的操作符优先级大 
                    //st->push(c);
                    break;
                }
                else if(y==2){            //俩操作符是'('和')'
                    st->pop();
                    return 0;
                }
                else
                    return -1;
            }
            st->push(c);
            return 0;
        }
        void test(){
            int i;
            cout<<num<<endl;
            for(i=0;i<num;i++){
                if(u[i].kind==1)
                    cout<<u[i].op<<" ";
                else if(u[i].kind==2)
                    cout<<u[i].num<<" ";
            }
        }
        int getResult(){
            int i;
            char op;
            double num1,num2;
            stack<double> st;
            for(i=0;i<num;i++){                    //处理后缀表达式 
                if(u[i].kind==2){                //如果是数字则入栈 
                    st.push(u[i].num);
                }
                else if(u[i].kind==1){            //如果是操作符,则出栈两个数字 
                    op=u[i].op;
                    if(st.empty())
                        return -1;
                    num2=st.top();
                    st.pop();
                    if(st.empty())
                        return -1;
                    num1=st.top();
                    st.pop();
                    switch(op){
                    case '+':
                        st.push(num1+num2);
                        break;
                    case '-':
                        st.push(num1-num2);
                        break;
                    case '*':
                        st.push(num1*num2);
                        break;
                    case '/':
                        if(num2==0)
                            return -1;
                        st.push(num1/num2);
                        break;
                    } 
                }
                else
                    return -1;
            }
            result=st.top();
            return 0;
        } 
        int getFResult(){
            int i;
            char op;
            fenshu f1(1,1),f2(1,1);
            stack<fenshu> st; 
            for(i=0;i<num;i++){
                if(u[i].kind==2){                //如果是数字则入栈 
                    st.push(fenshu(u[i].num,1));
                }
                else if(u[i].kind==1){            //如果是操作符,则出栈两个数字 
                    op=u[i].op;
                    if(st.empty())
                        return -1;
                    f2=st.top();
                    st.pop();
                    if(st.empty())
                        return -1;
                    f1=st.top();
                    st.pop();
                    switch(op){
                    case '+':
                        st.push(f1+f2);
                        break;
                    case '-':
                        st.push(f1-f2);
                        break;
                    case '*':
                        st.push(f1*f2);
                        break;
                    case '/':
                        if(f2.fz==0)
                            return -1;
                        st.push(f1/f2);
                        break;
                    } 
                }
                else
                    return -1;
            }
            fresult=st.top();
            return 0;
        } 
    }; 

    计算器类,核心类,可对符合标准的字符串进行识别与运算。

    int main(int argc, char** argv) {
        ifstream in("shit.txt");
        Calculator cal("");
        string s;
        string answer;
        int i=0,j;
        bool b;
        if(!in){
            cout<<"打开文件出错"<<endl;
            return -1;
        }
        else{
            while(in>>s){
                b=true;
                cal.recalculator(s);
                cal.run();
                cout<<""<<++i<<"题:"<<endl;
                cout<<s<<"=";
                cin>>answer;
                for(j=0;j<answer.size();j++){
                    if(answer[j]=='/'){
                        b=false;
                        break;
                    }
                }
                if(b){                                //用户输入为小数形式 
                    if(atof(answer.c_str())==cal.result)
                        b=true;
                    else
                        b=false; 
                }
                else{                                //用户输入为分数形式 
                    stringstream sst(answer);
                    int n1,n2;
                    char c;
                    sst>>n1>>c>>n2;
                    if(c!='/'){
                        cout<<"输入非法"<<endl; 
                    }
                    else{
                        fenshu f(n1,n2);
                        if(f==cal.fresult)
                            b=true;
                        else
                            b=false;
                    }
                }
                if(b){
                    cout<<"答案正确"<<endl; 
                }
                else{
                    cout<<"答案错误"<<endl;
                    cal.printfanswer();
                }
                cout<<endl;
            }
        }
        in.close();
        return 0;
    }

    main函数,包括了从文件中读取算式,并调用calculator中的函数等一系列操作,程序的主体。

    接下来的任务,尝试编写随机算式的生成。

  • 相关阅读:
    c语言l博客作业04
    【 js 基础 】【 源码学习 】 深浅拷贝
    【 js 片段 】如何组织表单的默认提交?【亲测有效】
    【 js 性能优化】【源码学习】underscore throttle 与 debounce 节流
    【 js 片段 】移动端适配简易步骤
    【 js 模块加载 】【源码学习】深入学习模块化加载(node.js 模块源码)
    【 js 片段 】点击空白或者页面其他地方,关闭弹框
    【 js 算法类】这么全的数组去重,你怕不怕?
    【 js 工具 】如何使用Git上传本地项目到github?(mac版)
    【 js 工具 】如何在Github Pages搭建自己写的页面?
  • 原文地址:https://www.cnblogs.com/chengyu404/p/5244908.html
Copyright © 2011-2022 走看看