// 未精简代码 #include <bits/stdc++.h> using namespace std; int main() { // 给出符号集合 按要求输出 // []内为符号 每个集合至少一个符号 ? 左手 // 集合不超过10 个 符号不超过4个字符 string h, e, m, tmp; // 定义三个 map 容器存不同符号 map<int, string> hand, eye, mouth; // 读取三行符号集 getline(cin, h); getline(cin, e); getline(cin, m); // 处理集合得到符号 for(int i = 0, num = 1; i < h.size(); i++){ // 如果是 '['则重置字符串 if(h[i] == '['){ tmp = ""; } // 如果是 ']'字符 将字符串放入 map 容器 else if(h[i] == ']'){ hand[num++] = tmp; } else{ // 拼接符号 tmp = tmp + h[i]; } } // 处理集合得到符号 for(int i = 0, num = 1; i < e.size(); i++){ // 如果是 '['则重置字符串 if(e[i] == '['){ tmp = ""; } // 如果是 ']'字符 将字符串放入 map 容器 else if(e[i] == ']'){ eye[num++] = tmp; } else{ // 拼接符号 tmp = tmp + e[i]; } } // 处理集合得到符号 for(int i = 0, num = 1; i < m.size(); i++){ // 如果是 '['则重置字符串 if(m[i] == '['){ tmp = ""; } // 如果是 ']'字符 将字符串放入 map 容器 else if(m[i] == ']'){ mouth[num++] = tmp; } else{ // 拼接符号 tmp = tmp + m[i]; } } // 读取请求个数 int k; cin >> k; int num[k][5]; for(int i = 0; i < k; i++) for(int j = 0; j < 5; j++) cin >> num[i][j]; for(int i = 0; i < k; i++){ // 判断是否可以输出表情 bool flag = true; // 0 1 2 3 4 // [左手] ([左眼] [口] [右眼]) [右手] for(int j = 0; j < 5; j++){ if(j == 0 || j == 4){ if(hand.find(num[i][j]) == hand.end()) { flag = false; break; } } else if(j == 1 || j == 3){ if(eye.find(num[i][j]) == eye.end()) { flag = false; break; } } else if(j == 2){ if(mouth.find(num[i][j]) == mouth.end()) { flag = false; break; } } } if(flag == true) for(int j = 0; j < 5; j++){ if(j == 0 || j == 4){ cout << hand[num[i][j]]; } else if(j == 1 || j == 3){ if(j == 1) cout << '('; cout << eye[num[i][j]]; if(j == 3) cout << ')'; } else if(j == 2){ cout << mouth[num[i][j]]; } // 序号不存在输出 } else cout << "Are you kidding me? @\\/@"; cout << endl; } }
// 精简后代码 #include <bits/stdc++.h> using namespace std; void process(map<int, string>& mp){ string tmp, str; // 读取符号集字符串 getline(cin, str); for(int i = 0, num = 1; i < str.size(); i++){ // 如果是 '['则重置字符串 if(str[i] == '['){ tmp = ""; } // 如果是 ']'字符 将字符串放入 map 容器 else if(str[i] == ']'){ mp[num++] = tmp; } else{ // 拼接符号 tmp = tmp + str[i]; } } } bool numIsTrue(int num, map<int, string>& mp){ if(mp.find(num) == mp.end()) return false; return true; } int main() { // 给出符号集合 按要求输出 // []内为符号 每个集合至少一个符号 ? 左手 // 集合不超过10 个 符号不超过4个字符 // 定义三个 map 容器存不同符号 map<int, string> hand, eye, mouth; // 读取并处理符号集 process(hand); process(eye); process(mouth); // 读取请求个数 int k, num[5]; cin >> k; for(int i = 0; i < k; i++){ // 读取一行序号 for(int i = 0; i < 5; i++) cin >> num[i]; // 0 1 2 3 4 // [左手] ([左眼] [口] [右眼]) [右手] if(numIsTrue(num[0], hand) && numIsTrue(num[1], eye) && numIsTrue(num[2], mouth) && numIsTrue(num[3], eye) && numIsTrue(num[4], hand)) cout << hand[num[0]] << '(' << eye[num[1]] << mouth[num[2]] << eye[num[3]] << ')' << hand[num[4]]; else cout << "Are you kidding me? @\\/@"; cout << endl; } }
当时不会函数传递引用,只能考复制粘贴和改变量名将就,所以代码写得臭长。看了下别人的文章,原来容器传递参数跟基本变量类型是类似的,而不是数组,直接就是地址。所以在函数参数类型后加一个 & 即可。
容器(vector)作为函数参数如何传参
参考别人更好的写法。原来判断符号是否存在,只需要对比读取进来的序号是否在容器元素个数的范围内。这个除了大于还得考虑小于的负数的情况(没想到还有负数的情况)。
这样写起来到时比我之前通过搜索容器的 key 的方式简洁不少。
if (a[0] > hand.size() || a[4] > hand.size() || a[1] > eye.size() || a[3] > eye.size() || a[2] > mouth.size() || a[0] < 1 || a[1] < 1 || a[2] < 1 || a[3] < 1 || a[4] < 1) //测试点2 cout << "Are you kidding me? @\\/@" << endl;
关于错误信息的输出里面有一个需要特殊处理,当时想不清楚到底是 \ 还是 / ,当然试了试可以发现 \ 反斜杠作为转义字符是需要变成 \\ 的。
int a[5]; for (int i = 0; i < 5; ++i) cin >> a[i];
本来写的方式以二维数组的方式读取进来,然后也是以二维数组来输出。参考别人可以在循环里面读取一行的数据,放在一维数组里面。想了想,直接命名5个变量并读取也不是不可以。
这样的后面也不需要搞一个循环变量来输出,直接读取下标就可以了。搞一个循环还要写判断语句,反而更麻烦。
也就说这种数据比较小的,直接手动给出下标输出就可以了,没必要搞一个判断。可能是前面的题目很多都是需要判断的,都成为下意识了。