我正在学习 Qt C++,有一个开始日期时间和一个结束日期时间,我想将其间的所有日期(包括开始日期和结束日期本身)分成 10 个槽。我不想要重复的日期,并且需要尽可能均匀且符合逻辑且整齐的分组。因此,例如,如果要处理 30 个日期,则每个槽位必须按时间顺序保存 3 个日期(可能会出现剩余天数,最后一个槽位将比其余槽位保存更少的日期)。然后我想将此数据存储在 QMap
假设我的开始日期是
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;
}
我感谢任何帮助,我真的很困惑,想不出任何想法。预先感谢您。
你不需要所有的恶作剧来纠正它。
想法很简单:
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;
}
在这个例子中,我选择将剩余的天数分配到最后的时段。