0

我正在编写一个代码,如果你输入你的生日日期和任何其他日期,它会返回你活着的年、月和日的总数。

Obs.:包括(闰)双六岁。

Obs.2:对于无效日期,输出必须是“data invalida”(葡萄牙语中的无效日期)。

输入/输出:

Obs.:日期格式为巴西标准,格式为日/月/年。


8 //第一个输入是您将测试的输入数量。


输入 1:29/02/2000

输入 2:01/03/2001

输出:1 0 1


输入 1:29/02/2000

输入 2:28/02/2001

输出:1 0 0


输入 1:29/12/2012

输入 2:2013 年 1 月 13 日

输出:0 0 15


输入 1:27/05/2012

输入 2:27/05/2013

输出:1 0 0


输入 1:2012 年 1 月 1 日

输入 2:2013 年 5 月 1 日

输出:1 0 4


输入 1:13/05/1966

输入 2:2015 年 5 月 2 日

输出:48 8 23


输入 1:29/02/2003

输入 2:2012 年 4 月 5 日

输出:数据无效


输入 1:1995 年 13 月 14 日

输入 2:1996 年 7 月 8 日

输出:数据无效


编码:

#include <iostream>
#include <cstdio>

using namespace std;

int verificar(int ano)
{
if (((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0))

    return 1;

else
    return 0;
}
int checkdia(int dia, int mes, int ano){    

if (dia>0)

    if (((mes==1)||(mes==3)||(mes==5)||(mes==7)||(mes==8)||(mes==10)||(mes==12)) && (dia<=31))
            return 1;

    else{

        if (((mes==4)||(mes==6)||(mes==9)||(mes==11)) && (dia<=30))

            return 1;

        else{

            if ((mes==2) && (dia<=28))

                return 1;

            else{

                if ((((verificar(ano))==true)&&(dia<=29))&&(mes==2))

                    return 1;

                else

                    return 0;
            }
        }
    }
else
return 0;
}

int checkmes(int mes)
{
if ((mes>0) && (mes<=12))
    return 1;
else
    return 0;
}

int checkano(int ano)
{
if ((ano>0) && (ano<11000))
    return 1;
else
    return 0;
}

int main(){

int numerodetestes, mes1, mes2, dia1, dia2, ano1, ano2, teste11, teste12, teste13, teste21, teste22, teste23;

cin>>numerodetestes;

for(int c=0;c<=numerodetestes;c++){

    scanf("%d/%d/%d", &dia1, &mes1, &ano1);
    scanf("%d/%d/%d", &dia2, &mes2, &ano2);

    teste11=checkano(ano1);
    teste12=checkdia(dia1,mes1,ano1);
    teste13=checkmes(mes1);
    teste21=checkano(ano2);
    teste22=checkdia(dia2,mes2,ano2);
    teste23=checkmes(mes2);

    if ((dia1==29)&&(mes1==02))
        dia1=28;

    if ((teste11+teste12+teste13+teste21+teste22+teste23)==6){
        total=((365*(ano2-ano1))+sexto);
                    //... incomplete part ...//
    }
    else
        cout<<"data invalida"<<endl;
}
return 0;
}

词汇表:

直径:天

我:月

无:年

numerodetestes:测试次数

verificar: bissextile 的函数

check(...): 检查“X”的函数

teste"XX": int 变量,将接收检查函数的 0 或 1。

问题是:我无法弄清楚如何以有组织的方式计算它。

4

1 回答 1

4

您应该使用bool而不是int您的返回值:

bool verificar(int ano)
{
    return ((ano % 4 == 0) && (ano % 100 != 0)) || (ano % 400 == 0));
}

您的check功能也可以大大简化:

bool checkmes(int mes)  {
    return ( (mes > 0) && (mes <= 12) );
}

bool checkano(int ano) {
    return ( (ano > 0) && (ano < 11000) );
}

bool checkdia(int dia, int mes, int ano) {   

    if(dia < 1 || dia > 31) return false;
    if(mes%2 == 0 && dia >30) return false;
    if(mes == 2 && dia >28) return verificar(ano);
    return true;
}

然后你可以写这样的东西:

bool checkdata(int dia, int mes, int ano) {
    return ( checkano(ano) && checkmes(mes) && checkdia(dia, mes, ano) );
}

这将允许你写:

if( !checkdata(dia1,mes1,ano1) || !checkdata(dia2,mes2,ano2) ) {
    cout<< "data invalida" <<endl;
}

现在对于主要问题,您可以轻松地估算出两个日期之间的天数,但您不能轻易地得到实数,因为日期只是合乎逻辑的。您必须考虑历史中的所有日历修改。

为了便于估计,我将首先添加/减去偏移到 1 月 1 日的日期,然后添加年份差异:

bool isLeap(int year) {
     return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}

int monthLengths[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int monthLength(int month, int year) {
    int n = monthLengths[month-1];
    if(month == 2 && isLeap(year)) n += 1;
    return n;
}

int yearLength(int year) {
    return isLeap(year) ? 366 : 365;
}


int nDay = 0; /* day counter */
/* subtract data1 offset to 01/01 */
nDay -= dia1;
for(int i = mes1; i > 1; --i) {
    nDay -= monthLength(i - 1, ano1);
}
/* add data2 offset to 01/01 */
nDay += dia2;
for(int i = mes2; i > 1; --i) {
    nDay += monthLength(i - 1, ano2);
}
/* add year offset */
for(int i = ano2; i > ano1; --i) {
    nDay  += yearLength(i);
}

cout << "Difference = " << nDay << " days" << endl;
于 2013-05-16T14:58:01.447 回答