所得皆所愿,所遇皆所求 2019-08-28 17:30 采纳率: 0%
浏览 3403
已结题

现在有一个需求,多个区间值求交集、并集、差集。

1.区间列表求交集、差集、并集
比如区间列表{[10-100],[120-200]} 减去 {[50-60],[65-70],[75-80]} 用代码怎么实现?

已经写了两个区间之间的计算方法,代码如下,但是列表相减会出现问题,有没有大佬解决过类型问题?
考虑过区间转成数组,但是由于范围可能会很大,所以排除此种解决方法。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class MsCrowdConditionDO {
    /**
     * 表名
     */
    private String tableName;

    /**
     * 字段名
     */
    private String fieldName;

    /**
     * 字段值起始
     */
    private String startValue;

    /**
     * 字段值结束
     */
    private String endValue;
}
/**
     * [两个区间值进行合并]
     *
     * @param rangeOne
     * @param rangeTwo
     * @param relation
     * @return java.util.List<MsCrowdAssembleDO>
     * @author LPF
     * @date 2019-08-23 15:52
     */
    public List<MsCrowdConditionDO> mergeRange(MsCrowdConditionDO rangeOne, MsCrowdConditionDO rangeTwo, Integer relation, String fieldName) {
        Integer minStartValue = Integer.MIN_VALUE;
        Integer maxEndValue = Integer.MAX_VALUE;
        if (ObjectUtils.isEmpty(rangeOne)) {
            rangeOne = new MsCrowdConditionDO("", fieldName, minStartValue.toString(), maxEndValue.toString());
        }
        if (ObjectUtils.isEmpty(rangeTwo)) {
            rangeTwo = new MsCrowdConditionDO("", fieldName, minStartValue.toString(), maxEndValue.toString());
        }
        if (ObjectUtils.isEmpty(rangeOne.getStartValue())) {
            rangeOne.setStartValue(minStartValue.toString());
        }
        if (ObjectUtils.isEmpty(rangeTwo.getStartValue())) {
            rangeTwo.setStartValue(minStartValue.toString());
        }
        if (ObjectUtils.isEmpty(rangeOne.getEndValue())) {
            rangeOne.setEndValue(minStartValue.toString());
        }
        if (ObjectUtils.isEmpty(rangeTwo.getEndValue())) {
            rangeTwo.setEndValue(minStartValue.toString());
        }
        List<MsCrowdConditionDO> list = new ArrayList<>();
        //并集
        if (relation.equals(RelationEnum.MERGE.getCode())) {
            list.add(rangeOne);
            list.add(rangeTwo);
        }
        //相减
        if (relation.equals(RelationEnum.SUBTRACTING.getCode())) {
            //区间1 包含于区间2中 相减为空
//            if (Double.valueOf(rangeOne.getStartValue()) >= Double.valueOf(rangeTwo.getStartValue())
//                    && Double.valueOf(rangeOne.getEndValue()) <= Double.valueOf(rangeTwo.getEndValue())) {
//            }
            //区间2的开始值  在区间1范围内
            if (Double.valueOf(rangeOne.getStartValue()) < Double.valueOf(rangeTwo.getStartValue())
                    && Double.valueOf(rangeTwo.getStartValue()) < Double.valueOf(rangeOne.getEndValue())) {
                list.add(new MsCrowdConditionDO("", fieldName, rangeOne.getStartValue(), rangeTwo.getStartValue()));
            }
            //区间2的结束值  在区间1范围内
            if (Double.valueOf(rangeOne.getEndValue()) > Double.valueOf(rangeTwo.getEndValue())
                    && Double.valueOf(rangeTwo.getEndValue()) > Double.valueOf(rangeOne.getStartValue())) {
                list.add(new MsCrowdConditionDO("", fieldName, rangeTwo.getEndValue(), rangeOne.getEndValue()));
            }
            //区间2的结束值小于区间1的开始值,或者区间2的开始值大于区间1的结束值,则相减为区间1本身
            if (Double.valueOf(rangeTwo.getEndValue()) < Double.valueOf(rangeOne.getStartValue())
                    || Double.valueOf(rangeTwo.getStartValue()) > Double.valueOf(rangeOne.getEndValue())) {
                list.add(rangeOne);
            }
        }
        //交集
        if (relation.equals(RelationEnum.INTERSECTION.getCode())) {
            String startValue = String.valueOf(Math.max(Double.valueOf(rangeOne.getStartValue()), Double.valueOf(rangeTwo.getStartValue())));
            String endValue = String.valueOf(Math.min(Double.valueOf(rangeOne.getEndValue()), Double.valueOf(rangeTwo.getEndValue())));
            if (Double.valueOf(startValue) <= Double.valueOf(endValue)) {
                list.add(new MsCrowdConditionDO("", fieldName, startValue, endValue));
            }
        }
        //排除
        if (relation.equals(RelationEnum.RULE_OUT.getCode())) {
            //并集
            List<MsCrowdConditionDO> allList = new ArrayList<>();
            allList.add(rangeOne);
            allList.add(rangeTwo);
            //交集
            List<MsCrowdConditionDO> sameList = new ArrayList<>();
            String startValue = String.valueOf(Math.max(Double.valueOf(rangeOne.getStartValue()), Double.valueOf(rangeTwo.getStartValue())));
            String endValue = String.valueOf(Math.min(Double.valueOf(rangeOne.getEndValue()), Double.valueOf(rangeTwo.getEndValue())));
            if (Double.valueOf(startValue) <= Double.valueOf(endValue)) {
                sameList.add(new MsCrowdConditionDO("", fieldName, startValue, endValue));
            }
            //并集减去交集
            if (!ObjectUtils.isEmpty(allList)) {
                if (ObjectUtils.isEmpty(sameList)) {
                    return allList;
                }
                for (MsCrowdConditionDO mcOne : allList) {
                    for (MsCrowdConditionDO mcTwo : sameList) {
                        //区间2的开始值  在区间1范围内
                        if (Double.valueOf(mcOne.getStartValue()) < Double.valueOf(mcTwo.getStartValue())
                                && Double.valueOf(mcTwo.getStartValue()) < Double.valueOf(mcOne.getEndValue())) {
                            list.add(new MsCrowdConditionDO("", fieldName, mcOne.getStartValue(), mcTwo.getStartValue()));
                        }
                        //区间2的结束值  在区间1范围内
                        if (Double.valueOf(mcOne.getEndValue()) > Double.valueOf(mcTwo.getEndValue())
                                && Double.valueOf(mcTwo.getEndValue()) > Double.valueOf(mcOne.getStartValue())) {
                            list.add(new MsCrowdConditionDO("", fieldName, mcTwo.getEndValue(), mcOne.getEndValue()));
                        }
                        //区间2的结束值小于区间1的开始值,或者区间2的开始值大于区间1的结束值,则相减为区间1本身
                        if (Double.valueOf(mcTwo.getEndValue()) < Double.valueOf(mcOne.getStartValue())
                                || Double.valueOf(mcTwo.getStartValue()) > Double.valueOf(mcOne.getEndValue())) {
                            list.add(mcOne);
                        }
                    }
                }
            }
        }
        return list;
    }
  • 写回答

2条回答 默认 最新

  • JonathanYan 2019-08-29 07:23
    关注

    你写的未免太复杂了吧。。。本来多简单的事非要搞成这样。。。其他人做这种事都是三两下就过了。。。
    第一,数组界限直接用int存不就得了,如果需要持久化到时候直接序列化就得了,毕竟是要参与计算的,要首先考虑局算的方便性。一堆string和double之间的转换真是让人佩服你的耐心。
    第二,你这个relation不应该在这么写,把所有情况分函数写好,然后写个总函数按照relation调用不同函数,你这样别人看着真是一头雾水。
    能不能改成int在做?而且你这里面有一堆冗余的判断,自己好好看看理清思路,在草稿纸上先写好计算过程再来实现。。。要是啥程序都这么写你是走不远的。。。

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器