CCF CSP 201712-3 Crontab
程序员文章站
2022-07-07 18:57:11
...
##源码
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <map>
#include <set>
using namespace std;
char vMon[][4]={"","jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};
char vWek[][4]={"sun","mon","tue","wed","thu","fri","sat"};
int mmon[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //定义每个月份的天数
map<string,int> mMon,mWek;
string inttostr(int i) //将int转换为string
{
stringstream ss;
ss<<i;
return ss.str();
}
int strtoint(string& str) //将string转换为int
{
int ans;
stringstream ss(str);
ss>>ans;
return ans;
}
vector<string> dealconfig(string& cfg,int tag) //根据tag处理各种配置信息
{
vector<string> vret; //定义返回的vector
cfg+=","; //给末尾加上,,好分割不同的区间
size_t lpos=0,rpos=cfg.find(",");
while(rpos!=string::npos)
{
string subs=cfg.substr(lpos,rpos-lpos);
size_t pos=subs.find("-"); //判断是否为连续值
if(pos==string::npos) //不是连续值
{
if(tag==0)
{
if(subs.size()==1)
{
subs="0"+subs;
vret.push_back(subs);
}
else vret.push_back(subs);
}
else if(tag==1)
{
if(isalpha(subs[lpos])) subs=inttostr(mMon[subs]); //将stirng转为数字再转为string
if(subs.size()==1)
{
subs="0"+subs;
}
vret.push_back(subs);
}
else if(tag==2)
{
if(isalpha(subs[lpos])) subs=inttostr(mWek[subs]); //将stirng转为数字再转为string
if(subs.size()==1)
{
subs="0"+subs;
}
vret.push_back(subs);
}
}
else //是连续值
{
string l=cfg.substr(lpos,pos-lpos),r=cfg.substr(pos+1,rpos-pos-1);
if(tag==0)
{
int left=strtoint(l),right=strtoint(r);
for(int i=left;i<=right;i++)
{
string temp=inttostr(i);
if(temp.size()==1)
temp="0"+temp;
vret.push_back(temp);
}
}
else if(tag==1)
{
if(isalpha(l[0])) l=inttostr(mMon[l]);
if(isalpha(r[0])) r=inttostr(mMon[r]);
int left=strtoint(l),right=strtoint(r);
for(int i=left;i<=right;i++)
{
string temp=inttostr(i);
if(temp.size()==1)
temp="0"+temp;
vret.push_back(temp);
}
}
else if(tag==2)
{
if(isalpha(l[0])) l=inttostr(mWek[l]);
if(isalpha(r[0])) r=inttostr(mWek[r]);
int left=strtoint(l),right=strtoint(r);
for(int i=left;i<=right;i++)
{
string temp=inttostr(i);
if(temp.size()==1)
temp="0"+temp;
vret.push_back(temp);
}
}
}
cfg=cfg.substr(rpos+1);
rpos=cfg.find(",");
}
return vret;
}
string getweekday(int y,int m,int d)
{
int tm=m>=3?(m-2):(m+10);
int ty=m>=3?y:(y-1);
int wd=(ty+ty/4-ty/100+ty/400+(int)(2.6*tm-0.2)+d)%7;
string wek="0"+inttostr(wd);
return wek;
}
bool isleapyear(int y) //判断是否是闰年
{
if((y%400==0)||(y%4==0&&y%100!=0))
return true;
else return false;
}
void tostandard(string& str) //将字符串转换为标准小写
{
for(int i=0;i<str.size();i++)
str[i]=tolower(str[i]);
}
void builtmap() //构建英文和数字的映射
{
for(int i=1;i<13;i++) mMon[vMon[i]]=i;
for(int i=0;i<7;i++) mWek[vWek[i]]=i;
}
int main()
{
//freopen("input/Crontab.txt","r",stdin);
map<string,vector<string> > output; //定义时间和命令的输出映射
int n;
string st,et; //开始时间,结束时间
builtmap();
cin>>n>>st>>et;
string ssy=st.substr(0,4),sey=et.substr(0,4);
int sy=strtoint(ssy),ey=strtoint(sey); //将年份转换为数字
while(n--)
{
string mts,hrs,dfm,mth,dfw,command; //分钟、小时、天数、月份、星期几
vector<string> vmts,vhrs,vdfm,vmth,vdfw; //vector存储可行的分钟小时等
cin>>mts>>hrs>>dfm>>mth>>dfw>>command;
tostandard(mth);
tostandard(dfw);
if(mts=="*") mts="0-59";
vmts=dealconfig(mts,0); //处理分钟
if(hrs=="*") hrs="0-23";
vhrs=dealconfig(hrs,0); //处理小时
if(dfm=="*") dfm="1-31";
vdfm=dealconfig(dfm,0); //处理天数
if(mth=="*") mth="1-12";
vmth=dealconfig(mth,1); //处理月份
if(dfw=="*") dfw="0-6";
vdfw=dealconfig(dfw,2); //处理星期
set<string> sdfw;
for(int i=0;i<vdfw.size();i++) sdfw.insert(vdfw[i]);
int cury=sy; //初始化当前年份
while(cury<=ey)
{
string sy=inttostr(cury);
if(isleapyear(cury)) mmon[2]=29; //是闰年
else mmon[2]=28; //不是闰年
for(int mi=0;mi<vmth.size();mi++) //取出所有可行月份
{
int im=strtoint(vmth[mi]);
string sm=vmth[mi];
for(int di=0;di<vdfm.size();di++)
{
int id=strtoint(vdfm[di]);
string sd=vdfm[di];
if(sdfw.count(getweekday(cury,im,id))==0||id>mmon[im]) //如果星期不符合或者日期大于月份最大天数
continue;
for(int Hi=0;Hi<vhrs.size();Hi++)
{
string sH=vhrs[Hi];
for(int Mi=0;Mi<vmts.size();Mi++)
{
string sM=vmts[Mi];
string curt=sy+sm+sd+sH+sM;
if(curt>=st&&curt<et) output[curt].push_back(command); //若还未到终止时间
}
}
}
}
cury++; //进入下一年
}
}
for(map<string,vector<string> >::iterator it=output.begin();it!=output.end();it++)
{
map<string,int> isprt;
vector<string> cmd=it->second;
for(int i=0;i<cmd.size();i++)
{
string out=it->first+" "+cmd[i];
if(isprt.count(out)==0)
{
cout<<out<<endl;
isprt[out]=1;
}
}
}
return 0;
}
上一篇: 【leetcode】BFS&DFS系列
下一篇: CentOS7.3安装NodeJS