用于验证间隔列表的算法
Algorithm to validate a list of intervals
给定开始/结束日期时间值的列表,我需要验证三件事:
- 对于每个间隔,开始时间早于结束时间
- 列表元素之间不存在重叠,每个开始/结束跨度必须表示整个列表中的离散间隔
- 系列不能有空档,从最早的开始到最晚的结尾都必须有连续的覆盖。
所以,给定:
( (1970-01-01, 1970-12-31), (1971-01-01, 1971-12-31), (1972-01-01, 1972-12-31), (1973-01-01, 1973-12-31) )
给出了成功的结果。
鉴于
( (1970-12-31, 1970-01-01), (1970-10-01, 1971-12-31), (1972-01-01, 1972-12-31), (1973-01-01, 1973-12-31) )
提供一条消息,指出开始日期在第一个元素中的结束日期之后。
鉴于
( (1970-01-01, 1970-12-31), (1970-10-01, 1971-12-31), (1972-01-01, 1972-12-31), (1973-01-01, 1973-12-31) )
提供了一条消息,指出第一个和第二个元素之间存在重叠。
鉴于
( (1970-01-01, 1970-12-31), (1971-10-01, 1971-12-31), (1973-01-01, 1973-12-31), (1974-01-01, 1974-12-31) )
提供了一条消息,指出第二个和第三个元素之间存在间隙。
第一个要求非常简单,问题是如何最好地将其纳入更广泛的验证中。
下面的文章在一定程度上满足了第二个要求,但由于它只适用于一对间隔,我仍然会意识到 O(n^2),因为每个元素都需要与其他元素进行比较,对吗?确定两个日期范围是否重叠
这篇文章 - 在区间列表中搜索区间重叠? - 似乎更好地解决了第二个要求,第一个可以滚动到区间树的填充中。
这就剩下第三个要求了。是否可以使用间隔树确定整个间隔中的间隙?
我会提到这是在Javascript中,node.js。但是,用Haskell或其他函数式语言解决这个问题会很有趣......
谢谢!
r/史蒂夫
这段代码提供了一个解决方案,尽管我假设以下内容:
- 您不介意对列表进行排序。它大大减少了比较次数要做。
- 根据您的示例,日期之间的比较是按天级别进行的。如果没有,您可能需要更改
strToDate
函数以及adjustment
变量。
这个想法取自@alfasin。
var data = [
['1970-01-01', '1970-12-31'],
['1971-01-01', '1971-12-31'],
['1972-01-01', '1972-12-31'],
['1973-01-01', '1973-12-31']
];
// comparison is in day level, adjust otherwise.
var adjustment = 1000 * 60 * 60 * 24;
var parsedData = [];
for(var idx = 0; idx < data.length; idx++) {
var thisItem = data[idx];
var thisParsedItem = [
Math.floor(strToDate(thisItem[0]).getTime() / adjustment),
Math.floor(strToDate(thisItem[1]).getTime() / adjustment),
// adding original items here, since I plan to sort the list.
thisItem[0],
thisItem[1]
];
parsedData.push(thisParsedItem);
}
parsedData = parsedData.sort(function (itemA, itemB) {
return itemA[0] - itemB[0];
});
var errorLocation = -1, overlap = false, gap = false, endBeforeStart = false;
for(var idx = 0; idx < parsedData.length - 1; idx++) {
// start before end.
if (parsedData[idx][0] > parsedData[idx][1]) {
errorLocation = idx;
endBeforeStart = true;
break;
}
var d = parsedData[idx + 1][0] - parsedData[idx][1];
// gap.
if (d > 1) {
errorLocation = idx + 1;
gap = true;
break;
}
// overlap.
if (d < 1) {
errorLocation = idx + 1;
overlap = true;
break;
}
}
if (errorLocation > -1) {
if (gap) { console.log("You have a gap at: " + errorLocation); }
if (overlap) { console.log("You have an overlap at: " + errorLocation); }
if (endBeforeStart) { console.log("End before start at: "
+ errorLocation); }
}
function strToDate(input) {
var parts = input.split('-');
return new Date(
parseInt(parts[0]),
parseInt(parts[1]),
parseInt(parts[2]));
}
首先使用类似的东西解析日期python中的datetime.datetime.strptime和将日期转换为毫秒并进行简单的检查。
在 Python 中以毫秒为单位获取当前时间?
如果不提供完整的工作示例,您可以执行以下操作:
- 按开始日期对列表进行排序(在排序功能中,您还可以验证是否
start < end
) - 循环访问列表并确保:
- 项是列表的第一项
- 开始日期比上一个停止日期多一个
我想这并没有真正降低函数的顺序(N x N log N),除非它已经排序并且您可以跳过步骤 1。
相关文章:
- 要求输入在数据列表中
- 从javascript创建一个列表
- 如何使用jQuery选择下拉列表的值
- 将输入字段中的文本提交到我的数据库,同时将其添加到我的列表中
- 将jsp文件下拉列表中的选定项分配给一个java变量(比如String selection)
- Javascript按钮下拉列表
- 如何使用json将对象列表从java转换为javascript
- 区分JSON中的矩阵和列表列表
- jQuery表单添加不适用于下拉列表
- 用每小时的差值填充数组/列表-从下拉列表中给定两个时间值
- 接受不在列表中的值-引导组合框
- 禁用jQuery中的下拉列表
- 循环比赛位置算法
- 从HTTPGET返回一个自定义对象列表,以便在Angular 2应用程序中使用
- 如何在javascript中迭代数字列表
- 用于验证间隔列表的算法
- 用于将类别树转换为平面列表的算法
- 从 n 个数组列表中查找最小数组的算法
- 一种算法,用于判断从列表中识别一个单词需要多少个不同的先导字符
- 递归算法,用于替换整数列表中单个给定整数的每个实例