题目描述:
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;
}