uva 502 DEL command(字符串处理)

232 篇文章 0 订阅
179 篇文章 0 订阅

  DEL command 

It is required to find out whether it is possible to delete given files from MS-DOS directory executing the DEL command of MS-DOS operation system only once. There are no nested subdirectories.

A note 

DEL command has the following format: DEL wildcard


The actual wildcard as well as a full file name can be made up either of a name containing 1 up to 8 characters or of a name and extension, containing up to 3 characters. The point character ``." separates the extension from the file name. The extension can be empty and this is equivalent to a name without any extension (in this case a wildcard ends with a point). In a wildcard the characters ``?" and ``*" can be used. A question mark substitutes exactly one character of the full file name excluding a point, an asterisk any sequence of characters (containing no points) even empty one. An asterisk can appear only at the last position of the name and the extension.


MS-DOS system can permit maybe other wildcards but they can not be used in this task. File names and extensions consist only of Latin capitals and digits.

Input 

The first line of the input is an integer M, then a blank line followed by M datasets. There is a blank line between datasets.

Input data for each dataset contains a list of full file names without empty lines and spaces. Each name is written in a separate line of input data file and preceded with a control sign: ``-" for delete or ``+" for keep. Full file names are not repeated. The list comprises at least one file, and at least one file is marked to be deleted. There are no more than 1000 files.

Output 

For each dataset, write to the first line of output the required DEL command (only one proposal) or  IMPOSSIBLE  if there is no solution. A space should separate `` DEL " from wildcard. Print a blank line between datasets.

Sample Input 

1

-BP.EXE
-BPC.EXE
+TURBO.EXE

Possible output 

DEL ?P*.*
题目大意:给出一些删除和保留的需求, 要求你给出一条命令,满足题目给出的需求。‘?'代表任意字母, '*'代表任意多个字母。

解题思路:首先将,文件名和扩展名分开储存, 在将删除和保留文件分开储存。

然后生成answer,对于每个删除文件的的每一位进行匹配, 相同填该字符, 不相同就填’?‘注意answer的长度要和最短删除文件名相同,如果删除文件名的最大值不等于最小值,要填充‘*’, 对文件名和拓展名均进行上面的操做。

然后对生成的answer进行匹配判断, 如果有删除保留文件,就输出不可能,否则输出answer.

#include <stdio.h>
#include <string.h>

const int N = 1010;

struct File{
    char sen_ori[N];
    char sen_exp[N];
}del[N], ret[N];
int cnt_del, cnt_ret;
int min_ori, min_exp;
int max_ori, max_exp;
char ans_ori[N], ans_exp[N];

void handle(char str[], char c) {
    int len = strlen(str), move = 1;
    if (c == '-') {
        for (int i = 0; move < len; move++) {
            if (str[move] == '.') {
                if (i > max_ori)    max_ori = i;
                if (i < min_ori)    min_ori = i;
                del[cnt_del].sen_ori[i] = '\0';
                break;
            }
            del[cnt_del].sen_ori[i++] = str[move];
            if (move == len - 1) {
                if (i > max_ori)    max_ori = i;
                if (i < min_ori)    min_ori = i;
                del[cnt_del].sen_ori[i] = '\0';
		break;
            }
        }
        
        move++;
	if (move >= len) {
	    min_exp = 0;
	}
	else {
	    for (int i = 0; move < len; move++) {
		del[cnt_del].sen_exp[i++] = str[move];
		if (move == len - 1) {
		    if (i > max_exp)    max_exp = i;
		    if (i < min_exp)    min_exp = i;
		    del[cnt_del].sen_exp[i] = '\0';
		}
	    }
	}
	del[cnt_del].sen_exp[min_exp] = '\0';
	cnt_del++;
    }
    else {
	for (int i = 0; move < len; move++) {
	    if (str[move] == '.') {
		ret[cnt_ret].sen_ori[i] = '\0';
		break;
	    }
	    ret[cnt_ret].sen_ori[i++] = str[move];
	    if (move == len - 1) {
		ret[cnt_ret].sen_ori[i] = '\0';
		break;
	    }
	}

	move++;

	for (int i = 0; move < len; move++) {
	    ret[cnt_ret].sen_exp[i++] = str[move];
	    if (move == len - 1) {
		ret[cnt_ret].sen_exp[i] = '\0';
	    }
	}
	ret[cnt_ret].sen_exp[move] = '\0';
	cnt_ret++;
    }
}

void slove() {
    // Init.
    memset(ans_ori, 0, sizeof(ans_ori));
    memset(ans_exp, 0, sizeof(ans_exp));

    for (int i = 0; i < min_ori; i++) {
	int flag = 1;
	for (int j = 1; j < cnt_del; j++) {
	    if (del[j].sen_ori[i] != del[0].sen_ori[i]) {
		flag = 0;
		break;
	    }
	}

	if (flag)
	    ans_ori[i] = del[0].sen_ori[i];
	else
	    ans_ori[i] = '?';
    }

    if (min_ori != max_ori) {
	ans_ori[min_ori] = '*';
	ans_ori[min_ori + 1] = '\0';
    }
    else
	ans_ori[min_ori] = '\0';

    for (int i = 0; i < min_exp; i++) {
	int flag = 1;
	for (int j = 1; j < cnt_del; j++) {
	    if (del[j].sen_exp[i] != del[0].sen_exp[i]) {
		flag = 0;
		break;
	    }
	}

	if (flag)
	    ans_exp[i] = del[0].sen_exp[i];
	else
	    ans_exp[i] = '?';
    }

    if (min_exp != max_exp) {
	ans_exp[min_exp] = '*';
	ans_exp[min_exp + 1] = '\0';
    }
    else
	ans_exp[min_exp] = '\0';
}

bool judge() {
    int len1 = strlen(ans_ori), len2 = strlen(ans_exp);
    if (ans_ori[len1 - 1] == '*')   len1--;
    if (ans_exp[len2 - 1] == '*')   len2--;

    for (int i = 0; i < cnt_ret; i++) {
	int flag = 1, dis1 = strlen(ret[i].sen_ori), dis2 = strlen(ret[i].sen_exp);

	for (int j = 0; j < len1; j++) {
	    if (ans_ori[j] == '?')  continue;
	    if (ans_ori[j] != ret[i].sen_ori[j]) {
		flag = 0;
		break;
	    }
	}

	if (flag) {
	    if (ans_ori[len1] == '*') {
		if (dis1 < len1)
		    flag = 0;
	    }
	    else if (len1 != dis1)
		flag = 0;
	}

	if (flag) {
	    for (int j = 0; j < len2; j++) {
		if (ans_exp[j] == '?')	continue;
		if (ans_exp[j] != ret[i].sen_exp[j]) {
		    flag = 0;
		    break;
		}
	    }
	}

	if (flag) {
	    if (ans_exp[len2] == '*') {
		if (dis2 < len2)
		    flag = 0;
	    }
	    else if (len2 != dis2)
		flag = 0;
	}

	if (flag)   return false;
    }
    return true;
}

int main() {
    int cas;
    scanf("%d%*c%*c", &cas);
    char str[N];

    while (cas--) {
	// Init.
	memset(del, 0, sizeof(del));
	memset(ret, 0, sizeof(ret));
	cnt_del = cnt_ret = 0;
	min_ori = min_exp = N;
	max_ori = max_exp = 0;

	// Read.
	while (gets(str) != NULL && str[0] != '\0') {
	    handle(str, str[0]);
	}
	slove();

	if(judge())
	    printf("DEL %s.%s\n", ans_ori, ans_exp);
	else
	    printf("IMPOSSIBLE\n");

	if (cas)
	    printf("\n");
    }
    return 0;}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值