|  | 
 
20鱼币 
| 任务描述 X同学最近非常烦,因为他正面对一大堆日期数据愁眉不展,原因是那些日期书写的极其不规范,不仔细辨别根本认不清是哪一天。
 以下每个日期中的三个数,年月日的位置是不确定的,假设其中最大的数表示年份,1-12范围的数表示月份,1-31范围的数表示日期,如果月日的范围都是1-12则按前月后日的顺序识别。
 例如:
 2/3-123     识别为0123年2月3日,合法;
 13+12+45    识别为0045年12月13日,合法;
 12=3=13     识别为0013年12月3日,合法;
 29,2,2019   识别为2019年2月29日,这一天不存在,不合法;
 12@12#12    识别为0012年12月12日,合法;
 35.36.37    识别为0037年XX月XX日,XX超出月份和日期范围,不合法;
 11*30*30    识别为0030年11月30日,合法;
 现在X要编程判断一下那些日期到底是否合法,你们说他能编出来吗。
 输入格式:
 一行,以X-Y-Z形式表示的一个日期,其中X、Y、Z为不超过4位的正整数,“-”为一个分隔字符,可能为任何符号。
 
 输出格式:
 若该日期为合法存在的日期,以“YYYY-MM-DD”的形式输出该日期的规范式,年4位,月日2位,不足前补0。
 若该日期为不合法日期,输出:Invalid Date!。
 
 输入样例:
 25-30-5
 输出样例:
 0030-05-25
 输入样例:
 2019-32-09
 输出样例:
 Invalid Date!
 输入样例:
 2019-30-09
 输出样例:
 2019-09-30
 
 麻烦用C语言,然后顺便讲解一下
 
 本帖最后由 jackz007 于 2023-11-12 14:29 编辑 
复制代码#include <stdio.h>
int leapyear(int y)
{
        return ((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0))) ? 1 : 0   ;  
}
int lastday(int y , int m)
{
        int d[] = {31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31} ;
        return (leapyear(y) && m == 2) ? 29 : d[m - 1]                        ;
}
int main(void)
{
        char c                                             ;
        int a , d , e[5] , f , i , k , m , y               ;
        for(;;) {
                for(i = 0 ; i < 3 ; i ++) e[i] = 0         ; // 每一轮输入-判断开始前,需要先将年月日数据清零
                for(i = k = 0 ; k < 3 ;) {
                        c = getchar()                      ;
                        if(c >= '0' && c <= '9') {
                                e[k] = e[k] * 10 + c - '0' ;
                                i ++                       ;
                        } else if(i) {
                                i = 0                      ;
                                k ++                       ;
                        }
                        if(c == '\n') break                ;
                }
                if(k == 3) {
                        for(a = 0 , i = 1 ; i < 3 ; i ++) if(e[i] > e[a]) a = i     ; // 取得数组 e[] 三个元素中值最大那个元素的索引值 a
                        for(i = 0 , m = 3 ; i < 3 ; i ++) if(i != a) e[m ++] = e[i] ; // 将数组 e[] 中除最大值外剩余的两个元素复制到 e[3] 和 e[4] 中
                        y = e[a]                                                    ; // 最大值 e[a] 为年,e[3]、e[4] 两个元素为月和日 
                        f = 0                                                       ; // 先将日期合法标志初始化为无效
                        if(e[3] >= 1 && e[3] <= 12 && e[4] >= 1 && e[4] <= lastday(y , e[3])) { // 将 e[3]、e[4] 分别作为月、日判断是否合法
                                m = e[3]                                            ; // 如果判断通过则执行这些代码
                                d = e[4]                                            ;
                                f ++                                                ;
                        } else if(e[4] >= 1 && e[4] <= 12 && e[3] >= 1 && e[3] <= lastday(y , e[4])) { // 将 e[3]、e[4] 分别作为日、月判断是否合法
                                m = e[4]                                            ; // 如果判断通过则执行这些代码
                                d = e[3]                                            ;
                                f ++                                                ;
                        }
                        if(f) printf("%04d-%d-%d\n" , y , m , d)                    ; // 根据判断标志确定年月日数据是否有效
                        else printf("Invalid Date !\n")                             ;
                } else if(! k) break                                                ;                                                               
        }
}
 | 
 |