简体   繁体   English

如何查找其他重叠数字范围之间的空闲数字范围

[英]How to find free number ranges between other overlapping number ranges

I have n Arrays. 我有n个数组。 Each array have m elements. 每个数组有m个元素。 Each element m consist of two attributes [numbers]. 每个元素m包含两个属性[数字]。

{
  start: x
  end: y
}

A start- and a end-number, both together describe a range. 起始编号和结束编号共同描述了一个范围。 So start is every time smaller than end. 因此,开始每次都小于结束。 I try to find the free number ranges (again with start and end), they are between the range elements in all arrays. 我尝试找到自由数范围(同样以开始和结束),它们在所有数组的范围元素之间。 Additional the result is bounded in an range. 另外,结果在一定范围内。

For example: 例如:

var boundary = {
    start: 0,
    end: 600
};

// for example i use two arrays with ranges, but in reality they are n (>= 1)
var numbersRanges1 = [
    {start: 100, end: 120},
    {start: 180, end: 200},
    {start: 400, end: 500}
];

var numbersRanges2 = [
    {start: 10, end: 80},
    {start: 150, end: 220},
    {start: 480, end: 500}
];

// result should look like
var expected = [
    {start: 0, end: 10},
    {start: 80, end: 100},
    {start: 120, end: 150},
    {start: 220, end: 400},
    {start: 500, end: 600}
];

That is my working solution at the moment ( JS Bin ) 这是我目前的工作解决方案( JS Bin

var boundary = {
    start: 0,
    end: 600
};

// for example i use two arrays with ranges, but in reality they are n (>= 1)
var numbersRanges1 = [
    {start: 100, end: 120},
    {start: 180, end: 200},
    {start: 400, end: 500}
];

var numbersRanges2 = [
    {start: 10, end: 80},
    {start: 150, end: 220},
    {start: 480, end: 500}
];

// result should look like
var expected = [
    {start: 0, end: 10},
    {start: 80, end: 100},
    {start: 120, end: 150},
    {start: 220, end: 400},
    {start: 500, end: 600}
];

// merge arrays
var mergedRanges = numbersRanges1.concat(numbersRanges2);


// sort by start
function sortByStart(a, b){
    return a.start - b.start;
}

mergedRanges = mergedRanges.sort(sortByStart);

// group overlapping ranges
for(var i = 1; i < mergedRanges.length; i++){
    var range1 = mergedRanges[i-1];
    var range2 = mergedRanges[i];

    if((range1.start <= range2.end) && (range1.end >= range2.start)){
        range2.start = Math.min(range1.start, range2.start);
        range2.end = Math.max(range1.end, range2.end);
        mergedRanges.splice(i-1, 1);
    }
}

// go throw merged ranges and save ranges between in addition array
var freeRanges = [];

if(mergedRanges[0].start > boundary.start){
    freeRanges.push({
        start: boundary.start,
        end: mergedRanges[0].start
    });
}

for(var i = 1, mergedLen = mergedRanges.length; i <  mergedLen; i++){
    freeRanges.push({
        start: mergedRanges[i-1].end,
        end: mergedRanges[i].start
    });
}

if(mergedRanges[mergedLen-1].end < boundary.end){
    freeRanges.push({
        start: mergedRanges[mergedLen-1].end,
        end: boundary.end
    });
}

console.log(freeRanges);
console.log(expected);

The script run on a node.js server. 该脚本在node.js服务器上运行。 Because we do a lot of concurrent calculation like these, i try to find an resource-efficient and performant algorithm for that. 因为我们像这样进行大量的并发计算,所以我尝试为此找到一种资源高效和高性能的算法。 Is there a better way to achieve that? 有没有更好的方法来实现这一目标? Are they any pitfalls in my code, that we lead to performance issues? 它们在我的代码中是否存在导致我们出现性能问题的陷阱?

Here's a simplified version for you. 这是给您的简化版本。

// for example i use two arrays with ranges, but in reality they are n (>= 1)
var numbersRanges1 = [
    {start: 100, end: 120},
    {start: 180, end: 200},
    {start: 400, end: 500}
];

var numbersRanges2 = [
    {start: 10, end: 80},
    {start: 150, end: 220},
    {start: 480, end: 500}
];

var boundary = {
    start: 0,
    end: 600
};

// merge arrays
var mergedRanges = numbersRanges1.concat(numbersRanges2);

// sort by start
function sortByStart(a, b){
    return a.start - b.start;
}

mergedRanges = mergedRanges.sort(sortByStart);

// go throw merged ranges and save ranges between in addition array
var freeRanges = [];

var start=0;
mergedRanges.forEach(function(one) {
  if(one.start<start) return;
  freeRanges.push({start:start,end:one.start});
  start=one.end;
});

if(start<boundary.end) {
  freeRanges.push({start:start,end:boundary.end});
}

console.log(JSON.stringify(freeRanges,null,2));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM