题目链接:http://118.190.20.162/view.page?gpid=T66
然后贴上一份别人比我写得好看的代码:https://blog.csdn.net/banana_cjb/article/details/79174688
不得不说,不提前规划好怎么写,或者不用C++的string,或者写代码的时候不够心细,处理起来是很恶心的。所以考试的时候一定要先写简单的部分,否则这题性价比挺低的,尤其是错了点细节可能会让你写了上百行的代码得20分。
本人遇到的问题:
1.数组下标写错。代码能力所致。
2.erase写错,因为是多重遍历,跳出循环需要处理一下字符串。所以提前规划好要怎么写是很重要的,不要中途改来改去。
3.日期数错。这个就尴尬了,用了一个数组记某个月过去这一年多少天,也就是31.28.31.30...的前缀数组。但是我算错了一个数,硬生生少了40分。
4.看错题忽略掉关键细节。首先Jun这种表示法,大小写都有可能。最后的15分看了别人的代码才发现错哪了。然后数据范围是左闭右开。
5.整数和字符串转化问题。不同于java,这里的string拼接整数,不能用+加号,或者直接构造,否则会出现奇怪的结果。然后整数转字符串可以注意一下补位的问题。
6.合法数据的额外判断。4月31号, 非闰年的2月29号等之类的数据要额外排除掉。
然后string的一些用法:
1.size()和length()。取得字符串长度。size等同于其他STL,length在string中刚好是同义词,就是说用哪个都可以。
2.at()和[]。取得某个位置的元素可以用at(i)后者直接下标访问。
3.+和append。用来拼接。append可以添加另一个字符的子串(string str, int pos, int len),或者多个相同字符(int time, char ch)
4.erase。用来删除从pos开始的len长度的字符(int pos, int len)。或删除一个或两个迭代器之间的字符。
5.find。用来查找某个字符串中某字符/串第一次出现的位置,没有返回npos。(str/char,pos=0).
6.substr。返回某个字符串从pos开始,长度为len的子串。
7.replace。把某个字符串,从pos开始,长度为len的串,替换成新串。(pos, len, string newstr)
然后处理逻辑:每个指令存5个string类型的vector,分别记录其合法分、小时、天、月、星期的两位字符串。通过遍历找到所有合法组,用星期和范围判断是否是一个指令,把拼接成的字符串存起来,最后通过排序得到按时间排序的指令集。
数据处理:
1.将Week和Month的英文串替换成数字。用两个数组遍历查找一遍即可。
2.将可能出现的数字替换成两位的字符串。可能会有补位问题。
3.处理*。如果是*将范围内所有数丢进vector。
4.否则按步骤循环处理每个,
5.在处理一组,隔开的解时,判断是否有-,有则转换整数将范围内所有数丢进vector,否则将整体丢进vector。
遍历判断:
1.通过5重循环(年、月、日、时、分)拼接字符串,一边拼接一边判断是否超过范围,超过修改str并continue.
2.遍历之前判重,避免插入重复数据(理论上来说不会)
3.走到最内层时。将特殊不合法日期去掉。并计算一下星期,查找是否在合法week_vector中,如果不在去掉。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const string Months[] = {" ", "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"};
const string Weekdays[] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat"};
const int Dnum[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365};
string sttime, edtime;//起止时间,左闭右开
typedef struct Ans
{
string time, work;
}Ans;
vector<Ans>ans;//答案组,多条指令不清空。
bool cmp(const Ans &