PAT福尔摩斯的约会

大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm。大侦探很快就明白了,字条上奇怪的乱码实际上就是约会的时间星期四 14:04,因为前面两字符串中第 1 对相同的大写英文字母(大小写有区分)是第 4 个字母 D,代表星期四;第 2 对相同的字符是 E ,那是第 5 个英文字母,代表一天里的第 14 个钟头(于是一天的 0 点到 23 点由数字 0 到 9、以及大写字母 A 到 N 表示);后面两字符串第 1 对相同的英文字母 s 出现在第 4 个位置(从 0 开始计数)上,代表第 4 分钟。现给定两对字符串,请帮助福尔摩斯解码得到约会的时间。

输入格式:
输入在 4 行中分别给出 4 个非空、不包含空格、且长度不超过 60 的字符串。

输出格式:
在一行中输出约会的时间,格式为 DAY HH:MM,其中 DAY 是某星期的 3 字符缩写,即 MON 表示星期一,TUE 表示星期二,WED 表示星期三,THU 表示星期四,FRI 表示星期五,SAT 表示星期六,SUN 表示星期日。题目输入保证每个测试存在唯一解。

输入样例:
3485djDkxh4hhGE
2984akDfkkkkggEdsb
s&hgsfdk
d&Hyscvnm
输出样例:
THU 14:04

#include<stdio.h>
#include<string.h>
#define N 61
int isWord(char msg){
    return msg >= 'a' && msg <= 'z' || msg >= 'A' && msg <= 'Z';
}
int main(){
    char msg[4][N],day,hour;//day表示星期几,hour表示几点
    int i,j,len1,len2,count = 1;//count用来判断是否为1,2个字符串中第一对相同的大写字母
    for(i = 0; i < 4; i++)
        gets(msg[i]);
    //获取前两个字符串中第一对和第二对相同的大写英文字母
    len1 = strlen(msg[0]);
    len2 = strlen(msg[1]);
    for(i = 0; i < len1 && i < len2; i++){
      /*
      如果当前的字符相同,我们并不能直接将其赋值给day,我们还需要判断当前
      的字符是否是我们想要的(也就是各个信息对应的字符范围我们也需要考
      虑),因为字符相同的时候,可能这些字符是其他的字符,比如'!',','之类
      的
      */
        if(msg[0][i] == msg[1][i]){
            if(count == 1){
            //如果count为1,并且当前的字符范围是再A~G,这是我们需要的,将其赋值给day
                if(msg[0][i] >= 'A' && msg[0][i] <= 'G'){
                      day = msg[0][i];
                      count++;
                }
            }else{
              /*如果count不为1,表明已经找到了第一队相同的大写字母,所以我
              们开始寻找day了,由于day的范围是0~9,A~N,所以再字符相同的情
              况下,我们只要直到其中一个字符msg[0][i]是否是再0~9,A~G的范
              围就可以了,而不用再判断msg[1][i]是否也在这个范围了
              */
                if(msg[0][i] >= '0' && msg[0][i] <= '9' || msg[0][i] >= 'A' && msg[0][i] <= 'N'){
                    hour = msg[0][i];
                    break;
                }
            }
        }
    }
    len1 = strlen(msg[2]);
    len2 = strlen(msg[3]);
    for(i = 0; i < len1 && i < len2; i++){
        if(msg[2][i] == msg[3][i] && isWord(msg[2][i])){
        /*
        如果当前的字符相同,并且msg[2][i]的范围是英文字母,那么我们就表明
        当前字符的下标是我们想要的,直接退出循环
        */
            break;
        }
    }
    //利用switch语句,将星期/时间输出
    switch(day){
        case 'A': printf("MON ");break;
        case 'B': printf("TUE ");break;
        case 'C': printf("WED ");break;
        case 'D': printf("THU ");break;
        case 'E': printf("FRI ");break;
        case 'F': printf("SAT ");break;
        case 'G': printf("SUN ");break;
    }
    
    switch(hour){
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
                  printf("0%c:",hour);
                  break;
        case 'A': printf("10:");break;
        case 'B': printf("11:");break;
        case 'C': printf("12:");break;
        case 'D': printf("13:");break;
        case 'E': printf("14:");break;
        case 'F': printf("15:");break;
        case 'G': printf("16:");break;
        case 'H': printf("17:");break;
        case 'I': printf("18:");break;
        case 'J': printf("19:");break;
        case 'K': printf("20:");break;
        case 'L': printf("21:");break;
        case 'M': printf("22:");break;
        case 'N': printf("23:");break;
    }
    printf("%02d\n",i);
    return 0;
}

在这里插入图片描述
通过上面的代码,我们可以看到,使用了大量的switch结构,可不可以再找到这个字符之后,将其输出呢?所以请看下面的优化代码:

#include<stdio.h>
#include<string.h>
#define N 61
int isWord(char msg){
    return msg >= 'A' && msg <= 'Z'|| msg >= 'a' && msg <= 'z';
}
int main(){
    char msg[4][N],week[7][4] = {"MON","TUE","WED","THU","FRI","SAT","SUN"};
    int i,len1,len2,count = 1;
    for(i = 0; i < 4; i++)
        gets(msg[i]);
    //获取前两个字符串中第一对和第二对相同的大写英文字母
    len1 = strlen(msg[0]);
    len2 = strlen(msg[1]);
    for(i = 0; i < len1 && i < len2; i++){
        if(msg[0][i] == msg[1][i]){
            //如果当前的字符相同,那么不可以直接就将器输出,因为有可能字符相同的是其他字符,比如'!',','这样的字符,所以我们需要避免这种情况
            if(count == 1){
                //count等于1表明的是第一对相同的字符
                if(msg[0][i] >= 'A' && msg[0][i] <= 'G'){
                    //如果这个字符是A~G,那么这才是我们想要的,因为题目要求是A~G是星期的,同时这样我们也避免上面说到的其他字符相同的情况
                    如果msg[0][i]是A,那么再week数组种的下标为0,所以如果msg[0][i]是B,那么减去'A',刚好等于1,对应week种的下标为1,输出TUE
                      printf("%s ",week[msg[0][i] - 'A']);
                      count++;
                }
            }else{
                //由于hour输出的时候,对应的字符是0~9,A~N,所以如果count!=1的时候我们需要判断当前的字符是否是这样的范围
                //将对应的数字输出之后,我们就退出循环
                if(msg[0][i] >= '0' && msg[0][i] <= '9'){
                     printf("0%c:",msg[0][i]);
                     break;
                }else if(msg[0][i] >= 'A' && msg[0][i] <= 'N'){
                    //如果是A~G,那么我们需要输出的是数字,这时候我们假设当前的字符是A,那么输出的是msg[0][i] - 'A' + 10 = 10,
                    //同样的,如果当前的字符msg[0][i]是B,那么输出为msg[0][i] - 'A' + 10 = 11
                    printf("%d:",msg[0][i] - 'A' + 10);
                    break;
                }
            }
        }
    }
    len1 = strlen(msg[2]);
    len2 = strlen(msg[3]);
    for(i = 0; i < len1 && i < len2; i++){
        if( msg[2][i] == msg[3][i] && isWord(msg[2][i])){
            //判断当前的字符相同,同时,我们还需要判断当前的字符是否是英文字符,如果是,那么就将其下标输出之后跳出循环,否则继续循环
                printf("%02d\n",i);
                break;
        }
    }
    return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值