欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CCF CSP 201712-3 Crontab

程序员文章站 2022-07-07 18:57:11
...

CCF CSP 201712-3 CrontabCCF CSP 201712-3 CrontabCCF CSP 201712-3 Crontab

##源码

#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;
} 
相关标签: CCF CSP