UVa 502 - DEL command

題目:有一些文件名(名字+擴展名),前面有±符號,-代表要刪除的文件,+代表要保留的文件;

            現在需要構造一個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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值