辅助判卷程序阶段性成果

目前已经大概完成程序的基础功能开发,实现功能为,读取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中的函数等一系列操作,程序的主体。

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

posted @ 2016-03-05 15:20  13070035王辰成  阅读(165)  评论(0编辑  收藏  举报