1

鉴于用户提供的这两个数据集,我正在尝试用 C 语言编写程序。年份:[范围 1901-2099] 和年份中的日期:[范围 1-366] 我需要一个公式来计算 MM/DD/YYYY 格式的日期。还有一件事。没有 IF/ELSE 语句。不允许 AND/OR 或 GREATER THAN 或 LESS THAN。

4

4 回答 4

2

您可以使用嵌套的 switch case 来避免使用 if-else。

  1. 看看是否是闰年。
  2. 创建四个月份的桶(1-99),(100-199)......等。桶号将用作案例号。
  3. 现在检查一天中最左边的位,并编写一个 switch case 将其分配到正确的存储桶中。
  4. 每个桶也可以再分成 4 个桶(将使用闰年信息)。
  5. 对中间位重复步骤 3,并根据结果(案例)切换到适当的存储桶。

简而言之,逻辑可能如下:

isLeapYear = year % 4

Switch(isLeapYear)
Case 0: {
  first_bucket = days/4
  Switch(first_bucket)
  {
   Case 0: {
            days_left = days % 100
            second_bucket = days / 50;
// ...
// ...
}
Case 1, 2, 3: {
// Similar logic for non-leap year
// ...
}
于 2013-09-28T04:02:04.863 回答
2

您可以在没有任何类型的流控制语句(if、switch)的情况下执行此操作,也无需自己进行闰年计算。获取与所需年份的 1 月 1 日相对应的时间戳。然后,您可以在时间戳上使用单个添加来获取正确的日期,并将时间戳转换为您想要的任何格式。

我会提供代码、特定的函数名称并解释您需要添加到时间戳中的内容,但由于这显然是一个家庭作业问题,所以我不会。如果有人在两周内提醒我(即作业的截止日期很可能已经结束),我会很乐意发布示例代码。

于 2013-09-28T04:52:08.437 回答
1

如果允许使用库函数(我对此表示怀疑),我会这样做(懒惰的乐高)方式:

#define _XOPEN_SOURCE /* glibc2 needs this for strptime */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>    
#include <errno.h>

int to_date(
  char * date, 
  const size_t size, 
  const char * fmt, 
  const short unsigned int day_of_year, 
  const short unsigned int year)
{
  char buffer[16] = "";

  sprintf(buffer, "%hu %hu", day_of_year, year);

  {
    struct tm t = {0};
    char * presult = strptime(buffer, "%j %Y", &t);

    if ((NULL == presult) || ('\0' != *presult))
    {
      errno = EINVAL;
      return -1;
    }

    strftime(date, size, fmt, &t);
  }

  return 0;
}

int main(int argc, char ** argv)
{
  if (2 > argc)
  {
    fprintf(stderr, "Missing arguments. Usage: %s day-of-year year\n", argv[0]);
    return EXIT_FAILURE;
  }

  short unsigned int day_of_year = atoi(argv[1]);
  short unsigned int year = atoi(argv[2]);
  char date[16] = "";

  if (-1 == to_date(date, sizeof(date), "%m/%d/%Y", day_of_year, year))
  {
    perror("to_date() failed");
    return EXIT_FAILURE;
  }

  printf("Result: day %d of year %d is '%s'.\n", day_of_year, year, date);

  return EXIT_SUCCESS;
}

像这样称呼它

$ ./main 2 2000

要得到

Result: day 2 of year 2000 is '01/02/2000'.    
于 2013-09-28T07:20:50.330 回答
0

对于 1901 年到 2099 年,可以使用时间函数轻松完成。

void Makedate(int year, int day, struct tm *dest) {
  struct tm tm1 = { 0 };
  // Leap year every 4 years, lets do calc referencing 2000-2003
  tm1.tm_year = 2000 - 1900 + year % 4;
  tm1.tm_mday = day; // Make the Jan 1st to Jan 366th.  OK to be out of range.
  // Avoid day changes due to DST by using Noon. BTW I doubt this is needed (CYA)
  tm1.tm_hour = 12;  
  // mktime adjusts our fields for us, setting the month, mday, dow, etc.
  mktime(&tm1);
  tm1.tm_year = year - 1900;  // set to selected year
  *dest = tm1;
}

int main() {
  struct tm tm0;
  Makedate(2013,   1, & tm0); printf("y:%4d m:%2d d:%2d\n", tm0.tm_year + 1900, tm0.tm_mon + 1, tm0.tm_mday);
  Makedate(2013, 365, & tm0); printf("y:%4d m:%2d d:%2d\n", tm0.tm_year + 1900, tm0.tm_mon + 1, tm0.tm_mday);
  Makedate(2020,   1, & tm0); printf("y:%4d m:%2d d:%2d\n", tm0.tm_year + 1900, tm0.tm_mon + 1, tm0.tm_mday);
  Makedate(2020, 366, & tm0); printf("y:%4d m:%2d d:%2d\n", tm0.tm_year + 1900, tm0.tm_mon + 1, tm0.tm_mday);
  return 0;
}

y:2013 m: 1 d: 1
y:2013 m:12 d:31
y:2020 m: 1 d: 1
y:2020 m:12 d:31
于 2013-09-28T04:23:35.963 回答