然后贴上一份别人比我写得好看的代码
不得不说,不提前规划好怎么写,或者不用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中,如果不在去掉。
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
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 &a, const Ans &b)
{
return a.time < b.time;
}
class Order
{
vector<string> mm, hh, DD, MM, Wek;
string work;
void init()
{
mm.clear(), hh.clear(), DD.clear(), MM.clear(), Wek.clear();
}
//----------- string和int转换--------------
int stoi(string str)
{
//cout<<"stoi:"<<str<<endl;
int ret = 0;
while(str != ""){
ret *= 10;
ret += str.at(0) - '0';
str = str.substr(1, str.size() - 1);
}
return ret;
}
string itos(int ipt)
{
string ret = "";
while(ipt)
{
char ch = ipt % 10 + '0';
ipt /= 10;
ret = ch + ret;
}
while(ret.size() < 2)ret = '0' + ret;
return ret;
}
//------------修改过的replaceAll(C++里没有)--------------
string replaceAll(string oldstr, string old_value, string new_value)
{
//cout<<"replaceAll"<<oldstr<<": "<<old_value<<"->"<<new_value<<endl;
int pos = 0;
for(int i = 0; i < oldstr.length(); i++)if(oldstr[i] <= 'Z' && oldstr[i] >= 'A')oldstr[i] = oldstr[i] - 'A' + 'a';
while((pos=oldstr.find(old_value))!=string::npos) {
oldstr = oldstr.replace(pos,old_value.size(),new_value);
}
return oldstr;
}
//------------分别处理5个数据。因为逻辑基本相同,理论上来说可以带上vector参数用一个函数实现。
void convMin(string str)
{
string strn;
string pb;
if(str == "*"){
for(int i = 0; i < 60; i++){pb = itos(i); mm.push_back(pb);}
}
else {
while(str != ""){
int pos;
if((pos = str.find(',')) != string::npos){
strn = str.substr(0, pos);
str = str.substr(pos+1, str.size() - pos);}
else {strn = str; str = "";}
int posn;
if((posn = strn.find('-')) != string::npos){
string left = strn.substr(0, posn);
int il = stoi(left);
string right = strn.substr(posn+1, strn.size()-posn);
int ir = stoi(right);
for(int i = il; i <= ir; i++){pb = itos(i); mm.push_back(pb);}
}
else mm.push_back(itos(stoi(strn)));
}
}
/*cout<<"mm:"<<endl;
for(int i = 0; i < mm.size(); i++)cout<<mm[i]<<" ";
cout<<endl;*/
}
void convHour(string str)
{
string strn;
string pb;
if(str == "*")for(int i = 0; i < 24; i++){pb = itos(i); hh.push_back(pb);}
else {
while(str != ""){
int pos, posn;
if((pos = str.find(',')) != string::npos){strn = str.substr(0, pos);str = str.substr(pos+1, str.size() - pos);}
else {strn = str; str = "";}
if((posn = strn.find('-')) != string::npos){
string left = strn.substr(0, posn);
int il = stoi(left);
string right = strn.substr(posn+1, strn.size()-posn);
int ir = stoi(right);
for(int i = il; i <= ir; i++){pb = itos(i); hh.push_back(pb);}
}
else hh.push_back(itos(stoi(strn)));
}
}
/*cout<<"hh:"<<endl;
for(int i = 0; i < hh.size(); i++)cout<<hh[i]<<" ";
cout<<endl;*/
}
void convDay(string str)
{
string strn;
string pb;
if(str == "*")for(int i = 1; i < 32; i++){pb = itos(i); DD.push_back(pb);}
else {
while(str != ""){
int pos, posn;
if((pos = str.find(',')) != string::npos){strn = str.substr(0, pos);str = str.substr(pos+1, str.size() - pos);}
else {strn = str; str = "";}
if((posn = strn.find('-')) != string::npos){
string left = strn.substr(0, posn);
int il = stoi(left);
string right = strn.substr(posn+1, strn.size()-posn);
int ir = stoi(right);
for(int i = il; i <= ir; i++){pb = itos(i); DD.push_back(pb);}
}
else DD.push_back(itos(stoi(strn)));
}
}
/*cout<<"DD:"<<endl;
for(int i = 0; i < DD.size(); i++)cout<<DD[i]<<" ";
cout<<endl;*/
}
void convMon(string str)
{
string strn;
string pb;
for(int i = 1; i <= 12; i++){
pb = itos(i);
str = replaceAll(str, Months[i], pb);
}
if(str == "*")for(int i = 1; i < 13; i++){pb = itos(i);MM.push_back(pb);}
else {
int pos, posn;
while(str != ""){
if((pos = str.find(',')) != string::npos){strn = str.substr(0, pos);str = str.substr(pos+1, str.size() - pos);}
else {strn = str; str = "";}
if((posn = strn.find('-')) != string::npos){
string left = strn.substr(0, posn);
int il = stoi(left);
string right = strn.substr(posn+1, strn.size()-posn);
int ir = stoi(right);
for(int i = il; i <= ir; i++){pb = itos(i);MM.push_back(pb);}
}
else MM.push_back(itos(stoi(strn)));
}
}
}
void convWek(string str)
{
string strn;
string pb;
for(int i = 0; i < 7; i++)
{
pb = itos(i);
str = replaceAll(str, Weekdays[i], pb);
}
if(str == "*")for(int i = 0; i < 7; i++){pb = itos(i); Wek.push_back(pb);}
else {
int pos , posn;
while(str != ""){
if((pos = str.find(',')) != string::npos){strn = str.substr(0, pos);str = str.substr(pos+1, str.size() - pos);}
else {strn = str; str = "";}
if((posn = strn.find('-')) != string::npos){
string left = strn.substr(0, posn);
int il = stoi(left);
string right = strn.substr(posn+1, strn.size()-posn);
int ir = stoi(right);
//cout<<left<<" -- "<<right<<endl;
for(int i = il; i <= ir; i++){pb = itos(i); Wek.push_back(pb);}
}
else Wek.push_back(itos(stoi(strn)));
}
}
return ;
}
//-------判断闰年和查找星期------------
bool luyear(int year)
{
return year%400 == 0 || (year%100 != 0 && year%4 == 0);
}
int getWeekday(string str)
{
int ans = 4;
int year = stoi(str.substr(0, 4));
int month = stoi(str.substr(4, 2));
int day = stoi(str.substr(6, 2));
for(int i = 1970; i < year; i++){
if(luyear(i))ans += 2;
else ans += 1;
}
ans %= 7;
ans += Dnum[month-1];
if(luyear(year) && month > 2)ans++;
ans %= 7;
ans += day-1;
ans %= 7;
return ans;
}
//创建ans组集
void getAns()
{
string str;
sort(mm.begin(), mm.end());
sort(hh.begin(), hh.end());
sort(DD.begin(), DD.end());
sort(MM.begin(), MM.end());
sort(Wek.begin(), Wek.end());
for(int y = stoi(sttime.substr(0, 4)); y <= stoi(edtime.substr(0, 4)); y++){
for(int l = 0; l < MM.size(); l++){
if(l > 0 && MM[l] == MM[l-1]){str.erase(4, 2);continue;}
str = itos(y) + MM[l];
if(str < sttime.substr(0, 6) || str > edtime.substr(0, 6)){str.erase(4, 2);continue;}
for(int k = 0; k < DD.size(); k++)
{
str = itos(y) + MM[l] + DD[k];
if(k > 0 && DD[k] == DD[k-1]){str.erase(6, 2);continue;}
if(str < sttime.substr(0, 8) || str > edtime.substr(0, 8)){str.erase(6, 2);continue;}
for(int j = 0; j < hh.size(); j++){
if(j > 0 && hh[j] == hh[j-1]){str.erase(8, 2);continue;}
str = itos(y) + MM[l] + DD[k] + hh[j];
if(str < sttime.substr(0, 10) || str > edtime.substr(0, 10)){str.erase(8, 2);continue;}
for(int i = 0; i < mm.size(); i++){
if(i > 0 && mm[i] == mm[i-1]){str.erase(10, 2);continue;}//判重
if(DD[k] == "31" && (MM[l] == "04" || MM[l] == "06" || MM[l] == "09" || MM[l] == "11" || MM[l] == "02")){str.erase(10, 2);continue;}//去掉非法日期
if(MM[l] == "02" && (DD[k] == "30" || (DD[k] == "29" && !luyear(y)))){str.erase(10, 2);continue;}
str = itos(y) + MM[l] + DD[k] + hh[j]+ mm[i] + '\0';
if(str < sttime.substr(0, 12) || str >= edtime.substr(0, 12)){str.erase(10, 2);continue;} //判断范围
int gwed = getWeekday(str);
string sgwed = itos(gwed);
bool flag = false;
for(int m = 0; m < Wek.size(); m++){//判断合法星期
if(Wek[m] == sgwed)flag = true;
}
if(flag == false){str.erase(10, 2);continue;}
Ans now;
now.time = str, now.work = work;ans.push_back(now);
str.erase(10, 2);
}
str.erase(8, 2);
}
str.erase(6, 2);
}
str.erase(4, 2);
}
str = "";
}
}
public:
Order(string a, string b, string c, string d, string e, string f)//构造函数直接调用
{
init();
work = f;
convMin(a);
convHour(b);
convDay(c);
convMon(d);
convWek(e);
getAns();
}
};
int main()
{
ans.clear();
int n;
cin>>n>>sttime>>edtime;
string a, b, c, d, e, w;
for(int i = 0; i < n; i++)
{
cin>>a>>b>>c>>d>>e>>w;
Order *ord = new Order(a, b, c, d, e, w);
}
sort(ans.begin(), ans.end(), cmp);//给所有合法指令集按时间排序。
for(int i = 0; i < ans.size(); i++)
{
cout<<ans[i].time<<" "<<ans[i].work<<endl;
}
return 0;
}