CCF CSP 201712-3 Crontab

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/IoT_fast/article/details/81806823

这里写图片描述这里写图片描述这里写图片描述

##源码

#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;
} 

猜你喜欢

转载自blog.csdn.net/IoT_fast/article/details/81806823