• 思考题:clock类编写


    题目

    为便于后文理解,这里先补上这份代码前文开的库以及宏定义:

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    #define f(a,b,c,d) for(register int a=b,c=d;a<=c;a++)
    #define g(a,b,c,d) for(register int a=b,c=d;a>=c;a--)
    typedef int i32;
    typedef unsigned int u32;
    typedef long long int i64;
    typedef unsigned long long int u64;
    

    开头

    考虑只有两个对象:时钟(CLOCK)与世界(WORLD)

    时钟的属性包括:时(Hour)、分(Mint)、秒(Secd)
    时钟的方法包括:增加(add)、重设(set)、查看(show)、清零(reset)、更新(update)

    世界的属性包括:时钟(x)、指令(order)
    世界的方法包括:错误抛出(error_solve)、指令识别(take_in)

    分析

    现在分别实现时钟与世界:

    时钟

    首先,对于时钟对象而言,其需要两个方法,一个将字符串转数字,一个将数字转字符串

    我们构造两个新方法:转数字(to_Num)与转字符串(to_s)

    转数字方法较好实现,就是输入 string 类储存的字符串,类似读入优化的方式计算出单个数字。只要记得加上特判:开头可以出现若干个负号,但中间不行;以及其它判定不能转化成数字的特判,即可简单实现:

    inline bool to_Num(string s,i32 &d_Num){
        d_Num=0;
        bool b_Neg=0,b_Start=0;
        f(i,0,I,s.size()-1){
            if(s[i]=='-'&&b_Start==0) b_Neg^=1;
            else if(s[i]>='0'&&s[i]<='9'){
                d_Num=d_Num*10+s[i]-48;
                b_Start=1;
            }
            else return 0;
        }
        if(b_Neg) d_Num=-d_Num;
        return 1;
    }
    

    转字符串方法考虑到一定是两位数转成字符串,所以也比较容易写出:

    inline string to_s(i32 d_Num){
        string s="";
        if(d_Num/10) s+=d_Num/10+'0';
        s+=d_Num%10+'0';
        return s;
    }
    

    接下来逐一实现上述的五个方法:

    增加方法

    根据输入的字符串转成的数字直接转成的秒数,加至原时间上,考虑时钟的特性,需要对秒数、分数、时数依次进位处理。再考虑到有用户会输入“时 分 秒”或"时:分:秒"形式,则增加转秒数(to_Sec)方法,将该类情况转成秒数,其余同样处理。记得将该正常情况以外的一切特殊情况特判为增加失败即可。

    inline void add(i64 d_Time){
        d_Secd+=d_Time%60;
        if(d_Secd>=60) d_Secd-=60,d_Mint++;
        d_Time/=60;
    
        d_Mint+=d_Time%60;
        if(d_Mint>=60) d_Mint-=60,d_Hour++;
        d_Time/=60;
    
        d_Hour+=d_Time;
        if(d_Hour>=24) d_Hour-=24;
    }
    inline bool add(string s){
        i32 d_Time;
        if(s.find(" ")!=string::npos) { if( !to_Sec(s,d_Time) ) return 0; }
        else { if( !to_Num(s,d_Time) ) return 0; }
        d_Time%=86400;
        if(d_Time<0) d_Time+=86400;
        add(d_Time);
        return 1;
    }
    

    而转秒数方法也较好实现,依次判定可否构成时、分、秒三个数字,然后用进率转为秒数返回即可:

    inline bool to_Sec(string ss,i32 &d_Time){
        f(i,0,I,ss.size()-1) if(ss[i]==':') ss[i]=' ';
    
        i32 h,m,s;
        string tmp;
        if(ss.find(" ")==string::npos) return 0;
        tmp=ss.substr( ss.find(" ")+1 );
        ss=ss.substr(0, ss.find(" ") );
        if( !to_Num(ss,h) ) return 0;
        
        ss=tmp;
        if(ss.find(" ")==string::npos) return 0;
        tmp=ss.substr( ss.find(" ")+1 );
        ss=ss.substr(0, ss.find(" ") );
        if( !to_Num(ss,m) ) return 0;
    
        ss=tmp;
        if(ss.find(" ")!=string::npos) return 0;
        if( !to_Num(ss,s) ) return 0;
    
        d_Time+=3600*h+60*m+s;
        return 1;
    }
    

    重设方法

    读入“时 分 秒”或“时:分:秒”形式的时间,如果时、分、秒任意一个不符合规范,即可判错。当然,转不成的也可以直接判错。

    inline void set(i32 h,i32 m,i32 s) { *this=CLOCK(h,m,s); }
    inline bool set(string ss){
        f(i,0,I,ss.size()-1) if(ss[i]==':') ss[i]=' ';
        
        i32 h,m,s;
        string tmp;
        if(ss.find(" ")==string::npos) return 0;
        tmp=ss.substr( ss.find(" ")+1 );
        ss=ss.substr(0, ss.find(" ") );
        if( !to_Num(ss,h) ) return 0;
        
        ss=tmp;
        if(ss.find(" ")==string::npos) return 0;
        tmp=ss.substr( ss.find(" ")+1 );
        ss=ss.substr(0, ss.find(" ") );
        if( !to_Num(ss,m) ) return 0;
    
        ss=tmp;
        if(ss.find(" ")!=string::npos) return 0;
        if( !to_Num(ss,s) ) return 0;
    
        if(h<0||h>=24||m<0||m>=60||s<0||s>=60) return 0;
        set(h,m,s);
        return 1;
    }
    

    查看方法

    直接调用前文的转字符串方法,返回“时:分:秒”形式的字符串即可

    inline string show(){ return to_s(d_Hour)+":"+to_s(d_Mint)+":"+to_s(d_Secd); }
    

    清零方法

    相当于重设为“0:0:0”

    inline void reset() { set(0,0,0); }
    

    更新方法

    相当于增加1秒

    inline void update() { add(1); }
    

    世界

    错误抛出方法

    直接输出即可

    inline void error_solve() { cout<<"Input error!"<<endl; }
    

    指令执行方法

    先判定空格的有无

    如果有空格,只能是增加、重设方法,否则都是输入格式错误;对于这两个方法,判定对应方法是否执行成功,不成功的需要抛出

    如果无空格,只能是查看、清零、更新方法,不需要判定是否执行成功,直接执行即可

    inline void take_in(string order){
        if(order.find(" ")!=string::npos){
            tmp=order.substr( order.find(" ")+1 );
            order=order.substr(0, order.find(" ") );
            if(order=="add") { if( !x.add(tmp) ) error_solve(); }
            else if(order=="set") { if( !x.set(tmp) ) error_solve();}
            else error_solve();
        }
        else{
            if(order=="show") cout<<x.show()<<endl;
            else if(order=="reset") x.reset();
            else if(order=="update") x.update();
            else error_solve();
        }
    }
    

    实现

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<map>
    using namespace std;
    #define f(a,b,c,d) for(register int a=b,c=d;a<=c;a++)
    #define g(a,b,c,d) for(register int a=b,c=d;a>=c;a--)
    typedef int i32;
    typedef unsigned int u32;
    typedef long long int i64;
    typedef unsigned long long int u64;
    
    class CLOCK{
        private:
            inline bool to_Num(string s,i32 &d_Num){
                d_Num=0;
                bool b_Neg=0,b_Start=0;
                f(i,0,I,s.size()-1){
                    if(s[i]=='-'&&b_Start==0) b_Neg^=1;
                    else if(s[i]>='0'&&s[i]<='9'){
                        d_Num=d_Num*10+s[i]-48;
                        b_Start=1;
                    }
                    else return 0;
                }
                if(b_Neg) d_Num=-d_Num;
                return 1;
            }
            inline string to_s(i32 d_Num){
                string s="";
                if(d_Num/10) s+=d_Num/10+'0';
                s+=d_Num%10+'0';
                return s;
            }
            int d_Hour,d_Mint,d_Secd;
            inline void add(i64 d_Time){
                d_Secd+=d_Time%60;
                if(d_Secd>=60) d_Secd-=60,d_Mint++;
                d_Time/=60;
    
                d_Mint+=d_Time%60;
                if(d_Mint>=60) d_Mint-=60,d_Hour++;
                d_Time/=60;
    
                d_Hour+=d_Time;
                if(d_Hour>=24) d_Hour-=24;
            }
            inline void set(i32 h,i32 m,i32 s) { *this=CLOCK(h,m,s); }
            inline bool to_Sec(string ss,i32 &d_Time){
                f(i,0,I,ss.size()-1) if(ss[i]==':') ss[i]=' ';
    
                i32 h,m,s;
                string tmp;
                if(ss.find(" ")==string::npos) return 0;
                tmp=ss.substr( ss.find(" ")+1 );
                ss=ss.substr(0, ss.find(" ") );
                if( !to_Num(ss,h) ) return 0;
                
                ss=tmp;
                if(ss.find(" ")==string::npos) return 0;
                tmp=ss.substr( ss.find(" ")+1 );
                ss=ss.substr(0, ss.find(" ") );
                if( !to_Num(ss,m) ) return 0;
    
                ss=tmp;
                if(ss.find(" ")!=string::npos) return 0;
                if( !to_Num(ss,s) ) return 0;
    
                d_Time+=3600*h+60*m+s;
                return 1;
            }
        public:
            CLOCK(i32 d_Hour_=0,i32 d_Mint_=0,i32 d_Secd_=0):d_Hour(d_Hour_),d_Mint(d_Mint_),d_Secd(d_Secd_) {}
            ~CLOCK() {}
            inline bool add(string s){
                i32 d_Time;
                if(s.find(" ")!=string::npos) { if( !to_Sec(s,d_Time) ) return 0; }
                else { if( !to_Num(s,d_Time) ) return 0; }
                d_Time%=86400;
                if(d_Time<0) d_Time+=86400;
                add(d_Time);
                return 1;
            }
            inline bool set(string ss){
                f(i,0,I,ss.size()-1) if(ss[i]==':') ss[i]=' ';
                
                i32 h,m,s;
                string tmp;
                if(ss.find(" ")==string::npos) return 0;
                tmp=ss.substr( ss.find(" ")+1 );
                ss=ss.substr(0, ss.find(" ") );
                if( !to_Num(ss,h) ) return 0;
                
                ss=tmp;
                if(ss.find(" ")==string::npos) return 0;
                tmp=ss.substr( ss.find(" ")+1 );
                ss=ss.substr(0, ss.find(" ") );
                if( !to_Num(ss,m) ) return 0;
    
                ss=tmp;
                if(ss.find(" ")!=string::npos) return 0;
                if( !to_Num(ss,s) ) return 0;
    
                if(h<0||h>=24||m<0||m>=60||s<0||s>=60) return 0;
                set(h,m,s);
                return 1;
            }
            inline string show(){ return to_s(d_Hour)+":"+to_s(d_Mint)+":"+to_s(d_Secd); }
            inline void reset() { set(0,0,0); }
            inline void update() { add(1); }
    };
    
    class WORLD{
        private:
            CLOCK x;
            string tmp;
            inline void error_solve() { cout<<"Input error!"<<endl; }
        public:
            WORLD() {}
            ~WORLD() {}
            inline void take_in(string order){
                if(order.find(" ")!=string::npos){
                    tmp=order.substr( order.find(" ")+1 );
                    order=order.substr(0, order.find(" ") );
                    if(order=="add") { if( !x.add(tmp) ) error_solve(); }
                    else if(order=="set") { if( !x.set(tmp) ) error_solve();}
                    else error_solve();
                }
                else{
                    if(order=="show") cout<<x.show()<<endl;
                    else if(order=="reset") x.reset();
                    else if(order=="update") x.update();
                    else error_solve();
                }
            }
    }w;
    
    int main(){
        string order;
        while( getline(cin,order) ) w.take_in(order);
        return 0;
    }
    
  • 相关阅读:
    JS判断年月
    斐波那契数列
    webkit 控件供vb 6 调用,不错~
    webkit com wrapper 推荐!
    firefox usercontrol for donet
    [z] How can we render CSS3 in a WebBrowser Control ?
    A simple way to crack VBA password in Excel file
    putty教程
    Putty建立隧道的方法[z]
    Step By Step Hibernate Tutorial Using eclipse WTP[z]
  • 原文地址:https://www.cnblogs.com/JustinRochester/p/12236169.html
Copyright © 2020-2023  润新知