題目:有一些文件名(名字+擴展名),前面有±符號,-代表要刪除的文件,+代表要保留的文件;
現在需要構造一個DEL 命令,DEL 後面接文件名,可以使用通配符?和*(只能在結尾),
求一個可行的DEL 命令。
分析:搜索。首先,構造出所有可能的情況,然後利用所有的文件名(保留和刪除)取判斷。
我的解題過程如下:
1.首先將文件名中的名字和擴展名分開(因為他們差不多,可以用一個函數分別處理);
2.通過刪除的文件名,構造刪除命令每個位置的字符集(?,*,可能還有某個字符);
因為*只出現在最後,不使用?時能構造的命令是所有要刪除的文件名的公共前綴加*;
在此基礎上,加入?的命令,就是可以利用?匹配的前綴加*(*可以沒有);
因而每個位置上只可能是?* 加上一個字符(如果所有要刪除的名字對應位置都是它);
3.利用dfs從上面的字符集中構造出所有可能的命令串(名字和擴展名分開處理);
這裡可能出現的名字不是很多:
名字:3+2*3+2*2*3+..+2^7*3 + 1 = 766(這裡的+1是指空串的情況);
擴展名:3+2*3+2*2*3 + 1 = 22;
4.枚舉上面的文件名和擴展名,利用所有的刪除和保留串找到合法的解;
匹配: *:直接匹配成功;
?:只要不空就成功;
其他:相同才成功;
如果所有的刪除文件都可以匹配並且保留的文件都不匹配即成功;
說明:╮(╯▽╰)╭。
#include <cstdio>
#include <cstring>
char del_name[1001][9];
char del_extension[1001][9];
char keep_name[1001][9];
char keep_extension[1001][9];
char del_name_letter[9][4];
char del_extension_letter[4][4];
char del_name_command[800][9];
char del_extension_command[30][9];
void divide_name(char sourse[], char name[], char extension[])
{
// get name from sourse string
int name_count = 0;
for (int i = 1; sourse[i]; ++ i) {
if (sourse[i] == '.' ) {
break;
}
name[name_count ++] = sourse[i];
}
for (int i = name_count; i < 9; ++ i) {
name[i] = 0;
}
// get extension from sourse string
int extension_count = 0;
if (name_count != 0) {
for (int i = name_count+2; sourse[i]; ++ i) {
extension[extension_count ++] = sourse[i];
}
}
for (int i = extension_count; i < 9; ++ i) {
extension[i] = 0;
}
}
void get_delete_letter(char del_str[][9], int del_size, int length, char del_letter[][4])
{
for (int i = 0; i < length; ++ i) {
char letter = 0;
for (int j = 0; j < del_size; ++ j) {
if (del_str[j][i]) {
letter = del_str[j][i];
break;
}
}
for (int j = 0; j < del_size; ++ j) {
if (del_str[j][i] && letter != del_str[j][i]) { // use '?'
letter = -1;
break;
}else if (!del_str[j][i] && letter) { // only can use '*'
letter = -2;
break;
}
}
int letter_count = 0;
if (letter != 0) {
if (letter != -2) {
if (letter != -1) { // at most, there is a letter except '?*'
del_letter[i][letter_count ++] = letter;
}
del_letter[i][letter_count ++] = '?';
}
del_letter[i][letter_count ++] = '*';
}
del_letter[i][letter_count ++] = 0;
}
}
int del_list_count;
char del_buf[9], del_buf_save[9];
void get_del_name(int deep, char del_letter[][4], char del_list[][9])
{
for (int i = 0; i < deep; ++ i) {
del_list[del_list_count][i] = del_buf[i];
}
for (int i = deep; i < 9; ++ i) {
del_list[del_list_count][i] = 0;
}
del_list_count ++;
if (deep && del_buf[deep-1] == '*') {
return;
}
if (del_letter[deep][0]) {
for (int i = 0; del_letter[deep][i]; ++ i) {
del_buf[deep] = del_letter[deep][i];
get_del_name(deep+1, del_letter, del_list);
}
}
}
bool match(char command[], char file[])
{
for (int i = 0; i < 9; ++ i) {
if (command[i] == '*') {
return true;
}else if (command[i] == '?') {
if (!file[i]) {
return false;
}
}else {
if (command[i] != file[i]) {
return false;
}
}
}
return true;
}
bool del(char name[], char extension[], int size)
{
for (int i = 0; i < size; ++ i) {
if (!match(name, del_name[i]) || !match(extension, del_extension[i])) {
return false;
}
}
return true;
}
bool keep(char name[], char extension[], int size)
{
for (int i = 0; i < size; ++ i) {
if (match(name, keep_name[i]) && match(extension, keep_extension[i])) {
return false;
}
}
return true;
}
int main()
{
int M;
char buf[20];
scanf("%d",&M);
getchar();
getchar();
while (M --) {
int keep_count = 0, del_count = 0;
while (gets(buf) && buf[0]) {
if (buf[0] == '-') {
divide_name(buf, del_name[del_count], del_extension[del_count]);
del_count ++;
}else {
divide_name(buf, keep_name[keep_count], keep_extension[keep_count]);
keep_count ++;
}
}
get_delete_letter(del_name, del_count, 9, del_name_letter);
get_delete_letter(del_extension, del_count, 4, del_extension_letter);
del_list_count = 0;
get_del_name(0, del_name_letter, del_name_command);
int del_name_command_size = del_list_count;
del_list_count = 0;
get_del_name(0, del_extension_letter, del_extension_command);
int del_extension_command_size = del_list_count;
int find_ans = 0, name_index = 0, extension_index = 0;
for (int i = 0; i < del_name_command_size; ++ i) {
for (int j = 0; j < del_extension_command_size; ++ j) {
if (del(del_name_command[i], del_extension_command[j], del_count) &&
keep(del_name_command[i], del_extension_command[j], keep_count)) {
find_ans = 1;
name_index = i;
extension_index = j;
break;
}
}
if (find_ans) {
break;
}
}
if (!find_ans) {
puts("IMPOSSIBLE");
}else {
printf("DEL %s.%s\n",del_name_command[name_index],
del_extension_command[extension_index]);
}
if (M) {
puts("");
}
}
return 0;
}