ccf201712-3-Crontab(100分)

题目描述:
这里写图片描述
这里写图片描述
这里写图片描述
c++代码:(做了两天,总算100分了,不过代码写的有点乱,还是要加油)
代码思路:

#include <iostream>
#include <vector>
#include <cstdio>
#include <set>
#include <algorithm>
#include <cctype>
#include <string>
#include <map>

using namespace std;


const int days[]={0,31,28,31,30,31,30,31,31,30,31,30,31};

map<string,int> mp;//用来把星期和月份的英文转换为数字




struct event {   //储存满足条件的时间
  int yy,mm,dd,hh,MM;
  int id;
  event(){}
  event(int y,int m,int d,int h,int M) :yy(y),mm(m),dd(d),hh(h),MM(M){}
  event(string s) { //这里处理输入的s和t,并把他们存储起来
    string tmp;
    tmp=s.substr(0,4);
    //cout << tmp <<endl;
    yy=0;
    int t=1000;
    for(int i=0;i<3;i++) {yy+=((tmp[i]-'0')*t);t/=10;}
    yy+=tmp[3]-'0';
    //cout << yy <<endl;
    tmp=s.substr(4,2);
    mm=0;
    mm+=(tmp[0]-'0')*10+tmp[1]-'0';
    tmp=s.substr(6,2);
    dd=0;
    dd+=(tmp[0]-'0')*10+tmp[1]-'0';
    tmp=s.substr(8,2);
    hh=0;
    hh+=(tmp[0]-'0')*10+tmp[1]-'0';
    tmp=s.substr(10,2);
    MM=0;
    MM+=(tmp[0]-'0')*10+tmp[1]-'0';
  }
  bool operator <(const event& b) const {
     return yy<b.yy||(yy==b.yy&&mm<b.mm)||(yy==b.yy&&mm==b.mm&&dd<b.dd)||(yy==b.yy&&mm==b.mm&&dd==b.dd&&hh<b.hh)||(yy==b.yy&&mm==b.mm&&dd==b.dd&&hh==b.hh&&MM<b.MM);
  }  //重载小于号用于之后的排序
  bool operator ==(const event& b) const {
     return yy==b.yy&&mm==b.mm&&dd==b.dd&&hh==b.hh&&MM==b.MM;
  } //判断时间是否完全相同
};
event year1,year2;
struct cron { //用于存储crontab信息
  event e;
  string cmd;
  int id;
  cron(event e1,int id1,string cmd1):e(e1),id(id1),cmd(cmd1){}
  bool operator < (const cron& b) const {
     return e<b.e||(e==b.e&&id<b.id);
  }
};


void read(string s,int p,int q,vector <int>& v) { //处理输入的crontab配置的五部分中的一部分
  for(int i=0;i<s.length();i++) {
           //cout << v.size() <<endl;
            int t;
        if(isdigit(s[i])) {
            if((i+1<s.length()&&isdigit(s[i+1]))) { //处理输入数据是两位数的情况
                    t=(s[i]-'0')*10+s[i+1]-'0';
                    i++;
            }
            else t=s[i]-'0';
            //cout << "?" <<endl;
            if(!count(v.begin(),v.end(),t)) //相同的时间只存储一次
            v.push_back(t);
        }
        else if(isalpha(s[i])) { //处理输入是英文的情况
                for(int k=0;k<3;k++) {
                    s[i+k]=tolower(s[i+k]);
                }
             t=mp[s.substr(i,3)];
            if(!count(v.begin(),v.end(),t))
            v.push_back(t);
            i+=2;
        }
        else if(s[i]==',')continue; //遇到逗号直接跳过
        else if(s[i]=='-') {
               int x=0; //处理到‘-’时,区间左值存储在变量t中
            if(isdigit(s[i+1])) {
            if(i+2<s.length()&&isdigit(s[i+2])) {
                    x=(s[i+1]-'0')*10+s[i+2]-'0';
                    i+=2;
            }
            else {x=s[i+1]-'0';i++;}
            }
            else if(isalpha(s[i+1])) {
                    for(int k=0;k<3;k++) {
                       s[i+1+k]=tolower(s[i+1+k]);
                    }
                 x=mp[s.substr(i+1,3)];
                i+=3;
            }
            //cout <<t<< x <<endl;

            for(int k=t+1;k<=x;k++)if(!count(v.begin(),v.end(),k))v.push_back(k);
        }
        else if(s[i]=='*') {
            for(int k=q;k<=p;k++){if(!count(v.begin(),v.end(),k))v.push_back(k);}
        }
         //for(int j=0;j<v.size();j++) cout << v[i]<<" "<<s <<endl;
   }
   //for(int i=0;i<v.size();i++) cout << v[i] <<endl;
}
vector <cron> v;
void solve(string mi,string h,string dm,string m,string dw,int id,string cmd) {
   vector <int> mit,hh,dmm,mm,dww;
   read(mi,59,0,mit);
   read(h,23,0,hh);
   read(dw,6,0,dww);
   read(dm,31,1,dmm);
   read(m,12,1,mm);
   int sy=year1.yy,sm=year1.mm,sd=year1.dd,sh=year1.hh,sM=year1.MM;
   int ey=year2.yy,em=year2.mm,ed=year2.dd,eh=year2.hh,eM=year2.MM;

   int xq=4;

   for(int i=1970;i<=ey;i++) {
       //if(i==2017)cout << xq <<endl;
       //cout << sy <<endl;
      if(i>=sy) { //到达起始年份
            int d=0;
         for(int j=1;j<=12;j++) {
                if(i==ey&&j>em)break;//处理已过终止年,退出
            if((i==sy&&j<sm)||(!count(mm.begin(),mm.end(),j))){xq+=days[j]+((j==2&&(i%400==0||(i%4==0&&i%100!=0)))?1:0);xq%=7;}
            //这里是处理到达起始年份,却没到达起始月份或者crontab配置中没包含这个月的情况
            else  {
                    //int l=1,r=days[j];
               for(int k=1;k<=days[j]+((j==2&&(i%400==0||(i%4==0&&i%100!=0)))?1:0);k++) {

                     if(i==ey&&j==em&&k>ed){xq+=1;xq%=7;break;} //处理到终止月份,退出
                        if(i==sy&&j==sm&&k<sd){xq+=1;xq%=7;continue;}
                              //if(i==2017&&j==11&&k==22)cout << xq <<endl;
                        //if(i==2017&&j==11&&k==22)for(int  w=0;w<dmm.size();w++)cout << "q"<<dmm[w]<<" ";
                  if(count(dmm.begin(),dmm.end(),k)) {
                        if(count(dww.begin(),dww.end(),xq)) {
                                //cout << xq <<endl;

                            for(int r=0;r<24;r++) {
                                    if(i==ey&&j==em&&k==ed&&r>eh)return;//如果小时也到达边界了,退出
                            if(count(hh.begin(),hh.end(),r)) //判断crontab配置中是否包含该小时
                            for(int c=0;c<60;c++) {
                                     if(i==ey&&j==em&&k==ed&&r==eh&&c>=eM)return;
                                     //cout <<mit[c] <<endl;
                                if(count(mit.begin(),mit.end(),c))
                                v.push_back(cron(event(i,j,k,r,c),id,cmd));
                                //同时满足crontab的5个条件,把它加入vector中
                            }
                           }

                        }
                    }
                   xq+=1;xq%=7; //处理星期的变化
               }
            }

         }
      }
      else {
          xq+=365+((i%400==0||(i%4==0&&i%100!=0))?1:0);
          xq%=7;
      }
   }
}

int main() {
    mp["jan"]=1;//用于把英文转为数字
mp["feb"]=2;
mp["mar"]=3;
mp["apr"]=4;
mp["may"]=5;
mp["jun"]=6;
mp["jul"]=7;
mp["aug"]=8;
mp["sep"]=9;
mp["oct"]=10;
mp["nov"]=11;
mp["dec"]=12;
mp["mon"]=1;
mp["tue"]=2;
mp["wed"]=3;
mp["thu"]=4;
mp["fri"]=5;
mp["sat"]=6;
mp["sun"]=0;

   int n;
   scanf("%d",&n);
   string y1,y2;
   cin >> y1 >> y2;
   year1=event(y1);year2=event(y2); //处理输入的s和t
   string mi,h,dm,m,dw,cmd;
   for(int i=0;i<n;i++) {
      cin >> mi >> h >> dm >> m >> dw>>cmd;
      solve(mi,h,dm,m,dw,i+1,cmd);
   }
   sort(v.begin(),v.end());//对处理过后得到的时间进行排序
   //cout << v.size() <<endl;
   for(int i=0;i<v.size();i++) {
      printf("%04d%02d%02d%02d%02d %s\n",v[i].e.yy,v[i].e.mm,v[i].e.dd,v[i].e.hh,v[i].e.MM,v[i].cmd.c_str());
   }
   return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值