简体   繁体   English

如何分割两个重叠的范围?

[英]How to split two overlapping ranges?

Looking for away to split two overlapping ranges when they overlap.当它们重叠时寻找分开两个重叠范围。

This is my current progress using typescript,这是我目前使用 typescript 的进展,

type Range = {
  start: number;
  end: number;
};
function splitOverlap(a: Range, b: Range): Range[][] {
  let result = [];
  const intersect = {
    start: Math.max(a.start, b.start),
    end: Math.min(a.end, b.end),
  };

  let a1: Range;
  let a2: Range;

  if (a.start >= intersect.start) {
    a1 = {
      start: a.start,
      end: Math.min(a.end, intersect.end),
    };

    a2 = {
      start: Math.max(a.start, intersect.start),
      end: Math.min(a.end, intersect.end),
    };
  } else if (a.start < intersect.start) {
    a1 = {
      start: a.start,
      end: Math.min(a.end, intersect.end),
    };

    a2 = {
      start: intersect.start,
      end: Math.min(a),
    };
  }

  return [
    [a1, a2],
    [b, b],
  ];
}

/* 
    Input
    A  |-------------|
    B         |-------------|

    Output
    A |-------|------|
    B         |------|------|

    Input
    A  |-------------|
    B     |-------|

    Output
    A  |--|-------|--|
    B     |-------|

*/

I am not required to do any merging, just splitting when there's overlap.我不需要进行任何合并,只需在重叠时进行拆分。

My split function first find the intersect between the ranges, then using the intersect data I think I can split the two input ranges.我的拆分 function 首先找到范围之间的相交,然后使用相交数据我想我可以拆分两个输入范围。 I don't know what is the best way to do it.我不知道最好的方法是什么。

Your requiremnt of two possiblities will fulfill, code is in JS您将满足两种可能性的要求,代码在 JS 中

 function split(a, b) { const start_first = a.start < b.start? a: b; const end_last = a.end > b.end? a: b; // 2nd requirement if(JSON.stringify(start_first) === JSON.stringify(end_last)) { const split1 = [{start: start_first.start, end: b.start}, {start: b.start, end: b.end},{start: b.end, end: a.end} ] const split2 = [{start: b.start, end: b.end},] return [split1, split2] } else { // 1st requirement const split1 = [{start: start_first.start, end: b.start}, {start: b.start, end: start_first.end}] const split2 = [{start: b.start, end: start_first.end}, {start: start_first.end, end: b.end}] return [split1, split2] } } console.log("first requirement Answer input{start: 10, end: 20},{start: 15, end: 25}::", split({start: 10, end: 20},{start: 15, end: 25})) console.log("second requirement Answer input: {start: 10, end: 30},{start: 15, end: 25}", split({start: 10, end: 30},{start: 15, end: 25}))

I finally did this我终于做到了

function splitOverlap(a: Range, b: Range): [Range[], Range[]] {
        const intersect: Range = {
            start: Math.max(a.start, b.start),
            end: Math.min(a.end, b.end),
        };

        const createRange = (range: Range, intersect: Range): Range[] => {
            const ranges = [...Object.values(getRange(range)), ...Object.values(intersect)];
            const uniqRanges = uniq(ranges.sort());
            const result = [];

            for (let i = 1; i < uniqRanges.length; i++) {
                const current = uniqRanges[i];
                const pre = uniqRanges[i - 1];

                result.push({
                    ...range,
                    start: pre,
                    end: current,
                });
            }

            return result;
        };

        const getRange = <T = any>({ start, end }: Range & T): Range => {
            return {
                start,
                end,
            };
        };

        const split1 = createRange(a, intersect);
        const split2 = createRange(b, intersect);

        return [split1, split2];
    }

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

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