在C ++中,使用循环查找任何给定日期的#天数?

时间:2014-06-30 10:23:06

标签: c++ date loops

是的,这是一项任务 - 所以请不要发布解决方案,但详细的伪代码非常有帮助!

我已经有一个C ++程序接受用户的日期,并确定它是否是闰年。

到目前为止,这是我的闰年功能(我希望这是正确的逻辑):

bool isLeapYear (int year){
    int leapYear = 0;

    //leapyear = 1 when true, = 0 when false
    if ((year%400 == 0) && (year%100 != 100)) {
        leapYear = 1;
        }
    else if (year%4 == 0) {
        leapYear = 1;
        }
    else {
        leapYear = 0;
        }



    if (leapYear == 1) {
        return 1;
    }
    else {
        return 0;
    }     
}

以下是我必须做的事情的解释:

  

你必须使用一个循环,每次增加一个月累积总和。   不要使用任何硬编码值   比如闰年前5个月的152个

为了澄清,这是我的第一个编程类,现在已经在这个C ++类中工作了大约一个月。 因此,如果有人能帮助我弄清楚如何使用循环语句来添加月数,我将不胜感激。 (IE:12/31/2013在非闰年应为“365”,在闰年应为“366”)。

我知道这是错的,但这是我到目前为止的函数“dayNumber”,它只是将一年中的天数返回到main函数(调用dayNumber函数):

int dayNumber (int day, int month, int year){
    //variable declarations
    int sumTotal = 0;


    for ( int loop = 1; loop < month; loop++) {
        sumTotal = (( month-1 ) * 31);
        sumTotal = sumTotal + day + 1;
        if ( (loop==4) || (loop=6) || (loop=9) ||
            (loop==11) ) {
            sumTotal = ( sumTotal - 1 );
        }
        else if ( isLeapYear(year) == 1 ) {
            sumTotal = (sumTotal - 2);
        }
        else  {
            sumTotal = (sumTotal - 3);
        }

    }


    return sumTotal;
}
是的,我开始捣乱它,以便在我知道的日子里获得适当的价值,但它有点搞砸了,哈哈。

如果有人对如何适当地进行循环有任何指导,我会非常感激!:)



修改: 好吧,我想我可能已回答了我自己的问题。

  

int dayNumber(int day,int month,int year){      //变量声明      int sumTotal = 0;

     

for(int loop = 1; loop&lt; month; loop ++){          sumTotal =(sumTotal + 31);

   if ( (loop==4) || (loop==6) || (loop==9) ||
       (loop==11) ) {
       sumTotal = ( sumTotal - 1 );
   }
     

}      if((month!= 2)&amp;&amp;(month&gt; 1)){          if(isLeapYear(year)== 1){              sumTotal =(sumTotal - 2);          }          其他{              sumTotal =(sumTotal - 3);          }      }

     

其他{          sumTotal = sumTotal;      }      sumTotal = sumTotal + day;

     

return sumTotal;   }

我绝对需要处理我的循环。 我很感激让我知道我的'='应该是'=='!

我相信这是一个使用足够简单的循环的合适代码? 我会测试更多日期。到目前为止,我只测试了类网站上提供的少数几个。

我无法回复自己的帖子,我的名声不够。

3 个答案:

答案 0 :(得分:3)

我知道答案已被接受,但我花了一些时间写自己的,让我们看看它是否可以增加一些信息。


让我们慢慢来看看。

首先,您的isLeapYear()功能并不完全正确。

如果不钻研算法部分,可以改进两到三件事。

  1. 您返回bool,但您的返回语句正在返回int。这本身并不错,但使用truefalse关键字可以提高可读性和一致性。

  2. 您应立即返回结果,而不是创建,分配和返回变量。

  3. 在您的运营商周围添加空格:year%400应该变为year % 400


  4. 现在你的代码。

    这个条件:

    if ((year%400 == 0) && (year%100 != 100))
    

    ......特别是这一部分:

    (year%100 != 100)
    

    不能做你期望的事。

    总的来说,算法如下:

      

    如果年份不能被4 整除 常见年份
      否则年度不能被100 整理 闰年   否则如果年份不能被400 整除 常见年份
      其他 闰年

    在代码中翻译:

    /**/ if (year % 4 != 0)
        return false;
    else if (year % 100 != 0)
        return true;
    else if (year % 400 != 0)
        return false;
    else
        return true;
    

    现在让我们简化一下:

    /**/ if (year % 4 == 0 && year % 100 != 0)
        return true;
    else if (year % 400 == 0)
        return true;
    else
        return false;
    

    再次:

    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        return true;
    else
        return false;
    

    最后,可以直接返回整个布尔表达式

    return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
    

    现在您的功能正确无误,让我们为您的dayNumber功能尝试算法:

    如果参数中提供的日期被认为是正确的,那么算法非常简单:

    • sum
    • 开始0
    • 从1循环到month排除
      • 如果month是Frebruary,则在isLeapYear返回true时添加29,否则为28
      • 如果month是1月,3月,5月,7月,8月,10月或12月,则添加31
      • 否则添加30
    • day添加到sum

答案 1 :(得分:0)

我知道提供详细的伪代码不仅仅是一个解决方案,但我还不是一个好老师:/祝你好运这个答案,并在你完成后睡个不醒:)


我假设dayNumber(8, 3, 1914)应该返回3月8日的1914年的ISO日期。

您想要做的是以下内容:

procedure dayNumber(theDay, theMonth, theYear):
    set answer to 1  // the first day of the year is day 1
    for every month 'thisMonth', up to and excluding theMonth:
        increment answer by the number of days in thisMonth
    increment answer by (theDay - 1)  // the first day of the month is monthday 1
    return answer

在迭代语句(或'循环体')中,有三种情况:

  1. 二月:如果是闰年,请将thisMonth增加29,否则增加28。
  2. 短月(4月,6月,9月,11月):增加30天。
  3. 否则,长月(1月,3月,5月,7月,8月,10月,12月):增加31天。
  4. 这转换为:

    if (thisMonth == 2) {
        // February
        if (isLeapYear(theYear))
            thisMonth += 29;
        else
            thisMonth += 28;
    } else if (thisMonth == 4 || thisMonth == 6 || thisMonth == 9 || thisMonth == 11) {
        // Short month
        thisMonth += 30;
    } else {
        // Long month
        thisMonth += 31;
    }
    

    (注意:X += YX = X + Y的缩写,或者应该是int dayNumber (int theDay, int theMonth, int theYear) { int result = 1; for (int thisMonth = 1; thisMonth < theMonth; thisMonth++) { /* ... see above ... */ } return result + theDay - 1; } 的简称。)

    你使用的循环逻辑看起来对我来说是正确的,除了1)逐个错误,因为你从第0天开始,2)在循环内而不是在循环之外添加月日:

    switch

    现在,关于使迭代语句更漂亮,基本上有两种方式(如果你的课程还没有涵盖它们,我当然建议不要在答案中使用它们)。一个是使用int dayNumber (int theDay, int theMonth, int theYear) { int monthDays[12] = { 31, 28, 31, 30, 31, 30, 31 , 31, 30, 31, 30, 31 } int result = 1; for (int thisMonth = 1; thisMonth < theMonth; thisMonth++) { if (thisMonth == 2 && isLeapYear(theYear)) // Special case: February in a leap year. result += 29; else /* Take the month length from the array. * Because C++'s array indices begin at 0, * but our first month is month 1, * we have to subtract one from thisMonth. */ result += monthDays[thisMonth - 1]; } return result + theDay - 1; } 语句,但我真的不喜欢它们,并且它没有提供比我已经提供的代码更多的好处。另一种方法是使用数组:

    {{1}}

答案 2 :(得分:0)

#include <ctime>
static int GetDaysInMonthOfTheDate(std::tm curDate)
{
    std::tm date = curDate;
    int i = 0;
    for (i = 29; i <= 31; i++)
    {
        date.tm_mday = i;
        mktime(&date);

        if (date1->tm_mon != curDate.tm_mon)
        {
            break;
        }
    }
    return i - 1;    
}