P1575题解
题目传送门
博客食用更佳
此题C党的题解大部分都是用栈来完成的,那么本蒟蒻就来写一个与所有题解都不同的方法。
大致思路:
- 首先读入一整行字符串。
- 进行特判,如果开头或末尾即为
and或or,或末尾为not,则直接输出error。 - 找出所有的
not,如果not后有or或and,直接输出error;如果存在多个not的情况,则把每两个not删除。最后只剩一个或零个not,若剩一个not,则把后边的一个单词反转(即true与false互换),并把not改为" "(三个空格)。 - 找出所有的
and,如果and前面的第一个单词与后面的第一个单词都是true,那么把and以及任意一个true全部赋值为空格,例如,true and true变为true(9个空格)。 - 找出所有的
or,方法与and基本一致。 - 最后判断字母t与字母f的个数,如果二者都有或任意一者多余一个,则输出
error,否则有1个t就输出true,有1个f就输出false。
注意:我们只需判断单词中的几个字母即可判断该单词为什么,因此不需要把整个单词分离判断。
步骤1&&步骤2(输入并特判):
//input
getline(cin, s);
int len = s.size();
if (s[0] == 'a' || s[0] == 'o' || s[len - 1] == 'd' || s[len - 1] == 'r' || s[len - 1] == 't') {
cout << "error";
return 0;
}
步骤3(处理not):
//not
for (int i = 0; i < len; i++) {
if (s[i] == 'n' && s[i + 1] == 'o') {
int j = i + 4;
while (s[j] == ' ') j++;
if (s[j] == 't')
s[j] = 'f', s[j + 1] = 'a', s[j + 2] = 's', s[j + 3] = 'e', s[i] = s[i + 1] = s[i + 2] = ' ';
//因为"true"是4个字母,"false"是5个字母,而中间的"l"没有用,所以可以这样做
else if (s[j] == 'f')
s[j] = 't', s[j + 1] = 'r', s[j + 2] = 'r', s[j + 3] = 'u', s[j + 4] = 'e', s[i] = s[i + 1] = s[i + 2] = ' ';
//道理同上
else if (s[j] == 'n')
s[i] = s[i + 1] = s[i + 2] = s[j] = s[j + 1] = s[j + 2] = ' ';
else {
cout << "error";
return 0;
}
}
}
步骤4(处理and):
//and
for (int i = 1; i < len; i++) {
if (s[i] == 'a' && s[i + 1] == 'n') {
int j = i - 2, k = i + 4;
while (s[j] == ' ') j--;//此时j为and上一个字母的末尾下标
while (s[k] == ' ') k++;//此时k为and后一个字母的首位下标
if (s[k] == 'a' && s[k + 1] == 'n') {
cout << "error";
return 0;
}//如果and后面还有and,就输出"error"
while (s[j] != ' ' && j != 0) j--;//此时j为and上一个字母的首位下标
while (s[k] != ' ' && k != len - 1) k++;//此时j为and上一个字母的末位下标
if (j != 0)
j++;
if (k != len - 1)
k--;
bool flag1 = false, flag2 = false;
if (s[j] == 't' && s[j + 1] == 'r')
flag1 = true;
if (s[k] == 'e' && s[k - 1] == 'u')
flag2 = true;
if (flag1 && flag2) {
s[j] = 't', s[j + 1] = 'r', s[j + 2] = 'u', s[j + 3] = 'e';
for (int l = j + 3 + 1; l <= k; l++)
s[l] = ' ';
}
else {
s[j] = 'f', s[j + 1] = 'a', s[j + 2] = 'l', s[j + 3] = 's', s[j + 4] = 'e';
for (int l = j + 4 + 1; l <= k; l++)
s[l] = ' ';
}
}
}
步骤5(处理or):
此步骤与步骤4几乎一模一样,将步骤4稍微修改即可,这里留给读者自己思考。
步骤6(输出):
//output
int t[200] = { 0 };//这里用了一个桶来统计字母出现的数量,t[s]表示为字母s出现的次数
for (int i = 0; i < len; i++) {
if (s[i] != ' ')
t[s[i]]++;
}
if (t['t'] > 1 || t['f'] > 1 || (t['t'] >= 1 && t['f'] >= 1)) {
cout << "error";
return 0;
}
else if (t['t'] == 1)
cout << "true";
else
cout << "false";