PAT---1029

来源:互联网 发布:农村淘宝村小二 编辑:程序博客网 时间:2024/06/04 01:02

1029. 旧键盘(20)

时间限制
200 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现。现在给出应该输入的一段文字、以及实际被输入的文字,请你列出肯定坏掉的那些键。

输入格式:

输入在2行中分别给出应该输入的文字、以及实际被输入的文字。每段文字是不超过80个字符的串,由字母A-Z(包括大、小写)、数字0-9、以及下划线“_”(代表空格)组成。题目保证2个字符串均非空。

输出格式:

按照发现顺序,在一行中输出坏掉的键。其中英文字母只输出大写,每个坏键只输出一次。题目保证至少有1个坏键。

输入样例:
7_This_is_a_test_hs_s_a_es
输出样例:
7TI

解题思路: 首先是读懂题目吧,本题上面字符串一定比下面字符串长!接下来我分2种情况考虑吧,其实我查了这么多,基本就是:暴力法 or   哈希映射

第一种:暴力法,时间复杂度是0(n2)

//双重循环---每个字符进行匹配#include <stdio.h>#include <string.h>#include <iostream>using namespace std;int main(void){    int i, j, k, m;    bool find1 = false, find2 = false;    char Old[80], New[80], lack[80] = {-1};  //char中可以初始化为 -1;    gets(Old);    //按照题意,Old > New;    gets(New);    for(i = 0, m = 0; i < strlen(Old); i++){        for(j = 0; j < strlen(New); j++)            if(toupper(New[j]) == toupper(Old[i]))    //预防大小写                find1 = true;    //好键盘        if(!find1){  //坏键盘            for(k = 0; k < strlen(lack); k++)                if(toupper(Old[i]) == toupper(lack[k]))                    find2 = true;        }         if(!find2)   //避免坏键盘                    lack[m++] = toupper(Old[i]);        find1 = false;        find2 = false;    }    for(i = 0; i < strlen(lack); i++)        cout<<lack[i];    return 0;}

· 结论:这里主要是将每个字符进行比较,即可避免重复输出,又清晰易懂

第二种:哈希映射,时间复杂度是 O(n)

#include <stdlib.h>#include <cstring>#include <iostream>using namespace std;int main(void){    int i = 0, k = 0, same = 0;    int key[128] = {0};       //全部初始化为0//    cout<<key[1]<<endl    char s1[80], s2[80];    char broken[80] = {'\0'};    cin>>s1>>s2;    //现在key[s1[i]]中s1[i]不再是字符,而是128个ascll中的一位    for(i = 0; i < strlen(s1); i++){        if(s1[i] >= 'a' && s1[i] <= 'z')            s1[i] -= 32;        key[s1[i]] = 1;    }    for(i = 0; i < strlen(s2); i++){        if(s2[i] >= 'a' && s2[i] <= 'z')            s2[i] -= 32;        key[s2[i]] = 0;    }    for(i = 0; i < strlen(s1); i++){     //扫描s1,若存在重复,则不输出        if(key[s1[i]] == 1){            key[s1[i]] == 0;     //防止重复            broken[k++] = s1[i];        }    }    for(i = 0; i < strlen(broken); i++)        cout<<broken[i];    cout<<endl;    return 0;}

结论:每个字符逐一进行匹配,应该都能想到,但是如何防止重复输出旧键盘呢?关键在于有key来充当约束.

下面我给出一段类似哈希映射的代码,和上面差不多,不过易懂

转载:

https://www.cnblogs.com/tangyikejun/p/4300395.html  

#include <cstdio>#include <map>#include <iostream>#include <cstring>using namespace std;int main(){        char str1[85],str2[85];    char str[85];    int ascii[200];        cin >> str1 >> str2;        memset(ascii, 0, sizeof(ascii));    memset(str, 0, sizeof(str));        int length = (int)strlen(str1);    int cnt = 0;    for (int i = 0; i < length; ++i) {        if (str2[cnt] != str1[i]) {            char ch = str1[i];            // 转为大写            if (ch >= 'a' && ch <= 'z'){                ch += 'Z' - 'z';            }            // 插入到map中            if (ascii[ch] == 0) {                ++ascii[ch];                int len = (int)strlen(str);                str[len] = ch;            }        }else{            ++cnt;        }    }        printf("%s\n",str);    return 0;}

结论:大家看下思想就可以了,我不建议弄map进去,但是每次比较一个字符一个字符很好理解,思想很Good

   (注:做一个大总结吧,每次做完PAT网上就有各种大神代码,以后收集起来,方便阅读。天冷了,多穿衣服吧。。。。。)