将 QDate 值均匀分配到一定数量的槽中

问题描述 投票:0回答:1

我正在学习 Qt C++,有一个开始日期时间和一个结束日期时间,我想将其间的所有日期(包括开始日期和结束日期本身)分成 10 个槽。我不想要重复的日期,并且需要尽可能均匀且符合逻辑且整齐的分组。因此,例如,如果要处理 30 个日期,则每个槽位必须按时间顺序保存 3 个日期(可能会出现剩余天数,最后一个槽位将比其余槽位保存更少的日期)。然后我想将此数据存储在 QMap 中,因此 int 将是槽号(1 到 10),QList 将保存每个组的开始日期和结束日期。

假设我的开始日期是

QDateTime startDateTime(QDate(2023,6,10), QTime(0,0,0));
,结束日期是
QDateTime endDateTime(QDate(2023, 6, 30), QTime(0,0,0));
,我希望结果是这样的:

 QMap((1, QList(QDate("2023-06-10"), QDate("2023-06-11")))(2, QList(QDate("2023-06-12"), QDate("2023-06-13")))(3, QList(QDate("2023-06-14"), QDate("2023-06-15")))(4, QList(QDate("2023-06-16"), QDate("2023-06-17")))(5, QList(QDate("2023-06-18"), QDate("2023-06-19"))), (6, QList(QDate("2023-06-20"), QDate("2023-06-21"))), (7, QList(QDate("2023-06-22"), QDate("2023-06-23"))), (8, QList(QDate("2023-06-24"), QDate("2023-06-25"))), (9, QList(QDate("2023-06-26"), QDate("2023-06-27"))), (10, QList(QDate("2023-06-28"), QDate("2023-06-30"))))

我不太明白如何处理诸如要分发几天的情况。另外,我自己的算法无法按预期工作,有时我的列表中会出现重复的日期。我在 Stack Overflow 上寻找了一个解决方案,但这些解决方案并不完全是我想要的(它们以一种方式分配值,其余的槽将填充相同的值,这不是我想要的)。

这是我的代码(ofc 它没有按预期工作)

#include <QMap>
#include <QList>
#include <QDateTime>
#include <QDebug>

QMap<int, QList<QDate>> splitDateTimeSlots(const QDateTime& startDateTime, const QDateTime& endDateTime, const QList<QDateTime>& parsedDateTimeList) {
    QMap<int, QList<QDate>> dateTimeInSlots;

    qint64 totalDays = startDateTime.date().daysTo(endDateTime.date());
    qDebug() << "Total days ->" << totalDays << "Each slot should contain" << totalDays/10.0;

    int slotsNum = 10;

    // Calculate the number of days per slot
    qint64 daysPerSlot = totalDays / slotsNum;
    qint64 remainder = totalDays % slotsNum;

    // Initialize variables for holding the start and end dates of each slot
    QDateTime slotStart = startDateTime;
    QDateTime slotEnd;

    for(int i = 0; i < slotsNum; ++i) {
        slotEnd = slotStart.addDays(daysPerSlot).addSecs(-1); // Subtract one second to make it end of the day
        qint64 daysInSlot = daysPerSlot;

        if(remainder > 0) {
            daysInSlot += 1;
            remainder--;
        }

        QDateTime slotEndAdjusted = slotEnd.addDays(1); // Move one day ahead to make it start of next day

        // Adjust slot end date if it goes beyond the specified endDateTime
        if (slotEndAdjusted > endDateTime) {
            slotEndAdjusted = endDateTime;
        }

        QList<QDate> slotDates;
        slotDates << slotStart.date() << slotEndAdjusted.date();

        // Add the start and end date of the slot to the map
        dateTimeInSlots[i+1] = slotDates;

        // Move the start date of the next slot to one day after the end date of the current slot
        slotStart = slotEndAdjusted.addDays(1);
    }

    return dateTimeInSlots;
}

int main() {
    QDateTime startDateTime(QDate(2023,6,10), QTime(0,0,0)); //selected start date and time
    QDateTime endDateTime(QDate(2023, 6, 23), QTime(0,0,0));//selected end date and time

    QList<QDateTime> parsedDateTimeList;
    parsedDateTimeList << QDateTime(QDate(2023,2,9), QTime(15,1,19)) << QDateTime(QDate(2023,4,3), QTime(14,59,8)) << QDateTime(QDate(2023,6,11), QTime(15,2,59)) << QDateTime(QDate(2023,6,29), QTime(15,1,16)) << QDateTime(QDate(2023,7,14), QTime(15,7,42));

    QMap<int, QList<QDate>> dateTimeInSlots = splitDateTimeSlots(startDateTime, endDateTime, parsedDateTimeList);

    // Output the result
    for (auto it = dateTimeInSlots.begin(); it != dateTimeInSlots.end(); ++it) {
        qDebug() << "Slot" << it.key() << ":";
        for (const auto& date : it.value()) {
            qDebug() << date.toString("yyyy-MM-dd");
        }
        qDebug() << "---------------------";
    }

    return 0;
}

我感谢任何帮助,我真的很困惑,想不出任何想法。预先感谢您。

c++ algorithm qt grouping qt6
1个回答
0
投票

你不需要所有的恶作剧来纠正它。

想法很简单:

  • 获取天数(包括边界)
  • 将天数除以所需的空位数量以获得空位大小
  • 迭代槽并附加日期,直到达到槽大小
  • 将剩余天数分配到时段(可以即时完成)

示例

QMap<unsigned int, QList<QDate>> sample(const QDate & start, const QDate & end, unsigned int nb_slots)
{
    QMap<unsigned int, QList<QDate>> result; // <slot number, slot samples>
    
    unsigned int days = start.daysTo(end) + 1; // +1 to count the end day in
    unsigned int slot_size = days / nb_slots;
    unsigned int days_left = days % nb_slots;

    unsigned int day_offset = 0;
    for(unsigned int n = 1; n <= nb_slots; ++n)
    {
        result.insert(n, QList<QDate>{});
        for(unsigned int i = 0; i < slot_size; ++i)
        {
            result[n].append(start.addDays(day_offset++));
        }

        // Distribute evenly remaining days (from the end)
        if(n > nb_slots - days_left)
            result[n].append(start.addDays(day_offset++));
    }
    
    return result;
}

实例

在这个例子中,我选择将剩余的天数分配到最后的时段。

© www.soinside.com 2019 - 2024. All rights reserved.