题意:一些文件名,包扩名字和扩展符,-是想要删除,+是想要保存,是否能找出一个字符串,做到此类型的都删除,不符合此类型的保存,找不出这样的字符串输出IMPOSSIBLE,这个字符串是有这个字母但不确定用‘?’代替,文件名末尾和扩展符末尾可以用‘*’代替一个长序列,当然‘*’也可以代表为空。
题解:模拟做就可以了,先分情况,不然思路会很乱(表示自己开始思路很乱的写了好久一直wa),先把给出的所有字符串分成4份,需要删除的和保留的,‘.’前面和后面的,然后找到需要删除的字符串'.'左右最短长度两个,如果在删除字符串中有比这个长度更长的,需要加'*',所以有4种情况,'.'前是否加'*','.'后是否加'*',然后和需要保留的字符串一一匹配,有星号要和长度大于等于自己的判断,没有星号直接判断长度和自己相等的就可以了,思路清晰就很好做了。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
using namespace std;
const int N = 1000 + 5;
string str[N];
string del1[N];
string del2[N];
string save1[N];
string save2[N];
char ans1[N];
char ans2[N];
int n, num1, num2, mind1, mind2, flag1, flag2, no1, no2;
void init() {
n = num1 = num2 = flag1 = flag2 = no1 = no2 = 0;
mind1 = mind2 = N;
for (int i = 0; i < N; i++)
save1[i] = save2[i] = del1[i] = del2[i] = "";
memset(ans2, 0, sizeof(ans2));
memset(ans1, 0, sizeof(ans1));
}
int main() {
int t, i, j;
scanf("%d", &t);
getchar();
getchar();
while (t--) {
init();
while (getline(cin, str[n])) {
if (str[n] != "")
n++;
else
break;
}
for (i = 0; i < n; i++) {
int len = str[i].size(), j;
if (str[i][0] == '+') {
for (j = 1; j < len; j++)
if (str[i][j] != '.')
save1[num1] += str[i][j];
else
break;
if (j != len)
for (j = j + 1; j < len; j++)
save2[num1] += str[i][j];
num1++;
}
else {
for (j = 1; j < len; j++)
if (str[i][j] != '.')
del1[num2] += str[i][j];
else
break;
if (mind1 > j - 1)
mind1 = j - 1;
if (mind2 > len - j - 1)
mind2 = len - j - 1;
if (j != len)
for (j = j + 1; j < len; j++)
del2[num2] += str[i][j];
num2++;
}
}
for (i = 0; i < mind1; i++) {
int temp = 0;
for (j = 0; j < num2 - 1; j++) {
if (del1[j][i] == del1[j + 1][i])
temp++;
}
if (temp == num2 - 1)
ans1[i] = del1[j][i];
else
ans1[i] = '?';
}
for (i = 0; i < mind2; i++) {
int temp = 0;
for (j = 0; j < num2 - 1; j++)
if (del2[j][i] == del2[j + 1][i])
temp++;
if (temp == num2 - 1)
ans2[i] = del2[j][i];
else
ans2[i] = '?';
}
for (j = 0; j < num2; j++) {
int len = del1[j].size();
if (len > mind1) {
flag1 = 1;
break;
}
}//文件名尾部是否有星号
for (j = 0; j < num2; j++) {
int len = del2[j].size();
if (len > mind2) {
flag2 = 1;
break;
}
}//扩展符尾部是否有星号
if (flag1) {
int i, j;
for (i = 0; i < num1; i++) {
int len = save1[i].size();
if (len < mind1)//pass
continue;
int temp = 0;
for (j = 0; j < mind1; j++) {
if (save1[i][j] == ans1[j] || ans1[j] == '?')
temp++;
}
if (temp == mind1) {
no1 = 1;
break;
}
}
}
if (flag2) {
int i, j;
for (i = 0; i < num1; i++) {
int len = save2[i].size();
if (len < mind2)//pass
continue;
int temp = 0;
for (j = 0; j < mind2; j++)
if (save2[i][j] == ans2[j] || ans2[j] == '?')
temp++;
if (temp == mind2) {
no2 = 1;
break;
}
}
}
if (!flag1) {
int i, j;
for (i = 0; i < num1; i++) {
int len = save1[i].size();
if (len != mind1)//pass
continue;
int temp = 0;
for (j = 0; j < mind1; j++)
if (save1[i][j] == ans1[j] || ans1[j] == '?')
temp++;
if (temp == mind1) {
no1 = 1;
break;
}
}
}
if (!flag2) {
int i, j;
for (i = 0; i < num1; i++) {
int len = save2[i].size();
if (len != mind2)//pass
continue;
int temp = 0;
for (j = 0; j < mind2; j++)
if (save2[i][j] == ans2[j] || ans2[j] == '?')
temp++;
if (temp == mind2) {
no2 = 1;
break;
}
}
}
if (no1 && no2)
printf("IMPOSSIBLE\n");
else {
printf("DEL ");
int i, j;
for (i = 0; i < mind1; i++)
printf("%c", ans1[i]);
if (flag1)
printf("*");
printf(".");
for (i = 0; i < mind2; i++)
printf("%c", ans2[i]);
if (flag2)
printf("*");
printf("\n");
}
if (t)
cout << endl;
}
return 0;
}