2020面向对象程序设计寒假作业1 题解

#include<cstdio>
#include<string>
#include<iostream>
#include<map>
#include<vector>
using namespace std;

vector<int> var_ar;
map<string,int> read_gbk,comd,var_id;
map<int,string> output_gbk;
/*
var_ar变量值
var_id从变量名到变量地址的映射
read_gbk将汉字转为数字
output_gbk将数字转成汉字
*/

inline void pre(){//初始化设置
    read_gbk["零"]=0;
    read_gbk["一"]=1;
    read_gbk["二"]=2;
    read_gbk["三"]=3;
    read_gbk["四"]=4;
    read_gbk["五"]=5;
    read_gbk["六"]=6;
    read_gbk["七"]=7;
    read_gbk["八"]=8;
    read_gbk["九"]=9;
    read_gbk["十"]=10;

    output_gbk[0]="零";
    output_gbk[1]="一";
    output_gbk[2]="二";
    output_gbk[3]="三";
    output_gbk[4]="四";
    output_gbk[5]="五";
    output_gbk[6]="六";
    output_gbk[7]="七";
    output_gbk[8]="八";
    output_gbk[9]="九";
    output_gbk[10]="十";

    comd["增加"]=1;
    comd["减少"]=-1;
    comd["等于"]=2;
    comd["看看"]=3;
    comd["整数"]=4;
}

inline void error_output(){//错误抛出
    puts("输入格式错误");
}
inline string gbk_output(int num){//数字转汉字(只输出0-99)
    string tmp="";
    if(num/10){
        if( (num/10)>1 ) tmp+=output_gbk[num/10];//不输出 一十* 的形式
        tmp+=output_gbk[10];
        if(num%10) tmp+=output_gbk[num%10];//*十的形式,不输出为 *十零 的形式
    }
    else tmp+=output_gbk[num%10];
    return tmp;
}

inline bool islegal(string s){ return read_gbk.find(s)!=read_gbk.end(); }//查询读入是否为数字对应的汉字
inline int gbk_read(string s){
    // return -1 means the input string is illegal
    int num=-1;
    string tmp;
    if( s.size()==2 ){
        if( !islegal(s) ) return -1;
        if(read_gbk[s]<10) s="零"+s;
        else s="一"+s;
    }//一位数和十,均凑成两位数
    if( s.size()==6 ){
        tmp=s.substr(2,2);
        if( !islegal(tmp) ) return -1;
        if( read_gbk[tmp]!=10 ) return -1;//查询第二个字是否为十,否则非法
        if( read_gbk[s.substr(0,2)]==10||read_gbk[s.substr(4,2)]==10 ) return -1;//查询一三是否为十,是则非法
        s=s.substr(0,2)+s.substr(4,2);//去掉中间,拼成两位数
    }
    if( s.size()==4 ){
        tmp=s.substr(0,2);
        if( !islegal(tmp) ) return -1;
        num=read_gbk[tmp];
        tmp=s.substr(2,2);
        if( !islegal(tmp) ) return -1;
        if(num<10) num*=10;//十* 的形式
        else if(tmp=="十") return -1;
        num+=read_gbk[tmp]%10;//*十 的形式
    }
    return num;
}

inline int number(string s){//读取用于运算的数字或变量
    int num=gbk_read(s);
    if(num>=0) return num;//先判定是否是数字
    if( var_id.find(s)!=var_id.end() ) return var_ar[ var_id[s] ];//再判定是否为变量
    return -1;//否则非法
}

inline bool iscomd(string s) { return comd.find(s)!=comd.end(); }//判定是否为合法指令
inline void carry(string s){
    string tmp="";
    int id;
    if( s.find(" ")==string::npos ){//不含空格,语句非法
        error_output();
        return ;
    }

    tmp=s.substr(0, s.find(" ") );
    s=s.substr( s.find(" ")+1 );

    if( !iscomd(tmp) ){//不是指令作为开头
        if( var_id.find(tmp)==var_id.end() ){//也不是变量(例如数字),或变量还未申请,语句非法
            error_output();
            return ;
        }

        id=var_id[tmp];//变量的地址
        if( s.find(" ")==string::npos ){//不含空格,语句非法
            error_output();
            return ;
        }

        tmp=s.substr(0, s.find(" ") );
        s=s.substr( s.find(" ")+1 );

        if( !iscomd(tmp) ){//不是指令,语句非法
            error_output();
            return ;
        }
        
        int command=comd[tmp];
        if(command!=-1&&command!=1&&command!=2){//不是加减或者赋值,语句非法
            error_output();
            return ;
        }

        int num=number(s);
        if(num<0){//语句非法
            error_output();
            return ;
        }
        if(command==-1) var_ar[id]-=num;
        else if(command==1) var_ar[id]+=num;
        else if(command==2) var_ar[id]=num;
    }
    else{//指令开头
        int command=comd[tmp];
        if(command==-1||command==1||command==2){//加减或赋值开头,语句非法
            error_output();
            return ;
        }
        if(command==3){
            int num=number(s);
            if(num<0){//输出未申请的变量,语句非法
                error_output();
                return ;
            }
            cout<<gbk_output(num)<<endl;
        }
        else{
            if( s.find(" ")==string::npos ){
                tmp=s;
                s="";
            }
            else{
                tmp=s.substr(0, s.find(" ") );
                s=s.substr( s.find(" ")+1  );
            }

            if( number(tmp)>=0 ){//变量已申请或者是数字对应的汉字,语句非法
                error_output();
                return ;
            }
            int id=var_id[tmp]=var_ar.size();
            var_ar.push_back(0);

            if(s=="") return ;//不赋初值,直接跳出

            if( s.find(" ")==string::npos ){//语句非法
                error_output();
                return ;
            }
            tmp=s.substr(0, s.find(" ") );
            s=s.substr( s.find(" ")+1 );

            if( iscomd(tmp)&&comd[tmp]==2 ){//赋初值
                int num=number(s);
                if(num>=0) var_ar[id]=num;
                else error_output();
            }
            else error_output();//语句非法
        }
    }
}

int main(){
    pre();
    string s;
    while( getline(cin,s) ) carry(s);//读入、分析并执行指令
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/JustinRochester/p/12217654.html