范围的差异差异、范围

由网友(陌上花开缓缓归)分享简介:如果我有以下的阵列,以重新presenting对整数范围内的每个元素:If I have the following arrays, with each element representing pairs of integer ranges:var a = [[0, 47], [50, 51], [53, 53]...

如果我有以下的阵列,以重新presenting对整数范围内的每个元素:

If I have the following arrays, with each element representing pairs of integer ranges:

var a = [[0, 47], [50, 51], [53, 53], [55, 55], [58, 97], [101, 101], [103, 1114111]];
var b = [[48, 57], [97, 102]];

我使用这code 为计算交会:

var output = [];

for (var i = 0; i < a.length; ++i) {
    for (var j = 0; j < b.length; ++j) {
        var intersection = [
        Math.max(a[i][0], b[j][0]),
        Math.min(a[i][1], b[j][1]), ];

        if (intersection[0] <= intersection[1]) {
            output.push(intersection)
        }
    }
}

console.log(JSON.stringify(output));

[ [ 50, 51 ], [ 53, 53 ], [ 55, 55 ], [ 97, 97 ], [ 101, 101 ] ]

我还需要为计算的的区别的(所有值0..1114111除了以上相交的范围)。

I also need to compute the difference (all values 0..1114111 except the ranges that intersect above).

什么是这样做的一个有效的方法?

What's an efficient way of doing that?

推荐答案

观察:所有值0..1114111除了上述交叉范围其实很简单,你只要遍历路口和输出它的补(连接端指向的以下时间间隔的开始点)。

Observation: "all values 0..1114111 except the ranges that intersect above" is actually trivial, you just iterate over the intersection and output its complement (connect end points to the start points of the following intervals).

所以你的问题简化为寻找交集更快。使用扫描线算法:

So your problem reduces to finding the intersection faster. Use a sweep line algorithm:

创建事件列表(T,X,Y),其中 T 是一个区间的边界点和 X 为1,如果间隔来自 A 2,如果它来自 B 为1,如果边界点为起点或-1,如果它是一个终点。 字典顺序排序按(T,Y) 设置计[1] =计数[2] = 0 遍历的事件点。更新计数[X] + = Y 。 Create a list of events (t, x, y) where t is the border point of an interval and x is 1 if the interval came from a and 2 if it came from b. y is 1 if the border point is a starting point or -1 if it is an end point. Sort lexicographically by (t, -y) Set count[1] = count[2] = 0 Iterate through the event points. Update count[x] += y.

现在的结果是范围,其中计[1] GT; 0 计数[2]&GT; 0 在同一时间。

Now the result are the ranges where count[1] > 0 and count[2] > 0 at the same time.

复杂度为O(n log n)的。这里有一个code例如: http://jsfiddle.net/QA5FY/14/ 感谢用户Xotic750提供的基本实现。

The complexity is O(n log n). Here's a code example: http://jsfiddle.net/QA5FY/14/ Thanks to user Xotic750 for providing the basic implementation.

Javascript的

Javascript

var a = [
    [0, 47],
    [50, 51],
    [53, 53],
    [55, 55],
    [58, 97],
    [101, 101],
    [103, 1114111]
];

var b = [
    [48, 57],
    [97, 102]
];

var evts = [];

function add(arr, x) {
    arr.forEach(function (pair) {
        evts.push({
            t: pair[0],
            x: x,
            y: 1
        }, {
            t: pair[1],
            x: x,
            y: -1
        });
    });
}

add(a, 0);
add(b, 1);

evts.sort(function (a, b) {
    return (a.t != b.t) ? (a.t - b.t) : (b.y - a.y);
});

var last = -1;
var count = [0, 0];
var res = [];

for (var i = 0; i < evts.length; ++i) {
    count[evts[i].x] += evts[i].y;
    if (count[evts[i].x] === 1 && count[evts[i].x ^ 1] > 0) last = i;
    else if (count[0] === 0 || count[1] === 0) {
        if (last >= 0) res.push([evts[last].t, evts[i].t]);
        last = -1;
    }
}

res.forEach(function (pair) {
    console.log(pair[0] + " " + pair[1]);
});

输出

50 51
53 53
55 55
97 97
101 101 
阅读全文

相关推荐

最新文章