Codefights RecurringTask问题

时间:2016-10-18 01:17:41

标签: c++ date

我在这个问题上被困了几个小时,我无法弄明白。有人能指出我正确的方向吗?

这是一个问题:

如果您有一项需要定期完成的任务,可以在Asana中将其设置为重复任务。一种选择是安排任务在一周的指定日期每k周重复一次。

能够查看安排任务的前n个日期会很有用。给定任务的第一个日期,返回前n个日期的数组。

在此任务中,您可能需要月份长度和工作日名称,如下所示:

1月至12月的月份长度:31,28,31,30,31,30,31,31,30,31,30,31。

闰年2月有29天。 工作日的名称:"星期天","星期一","星期二","星期三","星期四",& #34;星期五","星期六"。

2015年1月1日是星期四。 日期格式为dd / mm / yyyy。

实施例

对于firstDate =" 01/01 / 2015",k = 2,daysOfTheWeek = [" Monday"," Thursday"]和n = 4,输出应该是

recurringTask(firstDate, k, daysOfTheWeek, n) = 
    ["01/01/2015", "05/01/2015", "15/01/2015", "19/01/2015"]

感谢您提供任何帮助,这里是我的代码(我认为这是一个混乱,我只有3天才进入c ++)以防万一:

int dayofweek(int d, int m, int y){
    int t[] = { 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4 };
    y -= m < 3;
    return ( y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

std::vector<std::string> recurringTask(std::string firstDate, int k, std::vector<std::string> daysOfTheWeek, int n) {
    std::vector<std::string> ans = {firstDate};
    bool is_leap = false;
    //date to ints for firstDate
    int d = std::stoi(firstDate.substr(0, 2));
    int m = std::stoi(firstDate.substr(3, 2));
    int y = std::stoi(firstDate.substr(6));

    //check if leap
    int add_days = 7 * k;
    if((y % 4 == 0 && y % 100 != 0) || y % 400 == 0){
        is_leap = true;
    }

    for(int i = 1; i < n; i++){
        for(int j = 1; j < daysOfTheWeek.size(); j++){
            int max_d = 31;
            //month
            if(m == 2){
                if(is_leap){
                    max_d = 29;
                }else {
                    max_d = 28;
                }
            }else{
                max_d = 30;
            }

            if(d + add_days > max_d){
                //Go to next month
                d = d + add_days - max_d;
                m += 1;
                if(m > 12){
                    //Go to next year.
                    m = 1;
                    y += 1;
                }
                ans.push_back(std::to_string(d) + "/" + std::to_string(m) + "/" + std::to_string(y));
            }else{
                d += add_days;
                ans.push_back(std::to_string(d) + "/" + std::to_string(m) + "/" + std::to_string(y));
            }

        }
    }

    return ans;
}

1 个答案:

答案 0 :(得分:1)

你走在正确的轨道上。

首先,你的max_d逻辑是错误的。 Max_d取决于月份。

vector<int> max_d{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

针对该向量查询它。也做闰年检查。棘手的部分给出了daysOfTheWeek向量,你需要构建另一个向量,按照你的开始日期顺序保存一周的所有日期。我的意思是

首先,您可以保证在daysOfTheWeek矢量中的星期几开始日期

如果daysOfTheWeek = [“Monday”,“Thursday”]并且您的开始日期是星期四,则需要创建一个以数字形式保存相应日期的向量。

vector<string> weekDays{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

针对该向量查询它。所以逻辑是,我采用daysOfTheWeek向量并创建一个新的向量,保存天数的数字形式。所以这个向量应该包含[1,4]的星期一和星期四。现在我重新排列这个向量,以便在保持顺序的同时开始第一天......所以它变为[4,1]。现在我弹出前面所以向量刚刚变为[1]并且对于每个任务,我只需要打印开始日期并循环通过刚创建的这个向量并将每个元素添加到你的开始日期并打印。

deque<int> dow;
    for (int i = 0; i < daysOfTheWeek.size(); i++){
        for (int j = 0; j < weekDays.size(); j++){
            if (daysOfTheWeek[i] == weekDays[j]){
                dow.push_back(j);
                break;
            }
        }
    }

    int startDow = dayofweek(stoi(day), stoi(month), stoi(year));
    while (dow.front() != startDow){
        dow.push_back(dow.front());
        dow.pop_front();
    }
    dow.pop_front();