当前位置: 首页 > 面试题库 >

有什么好的通用算法可以折叠一组可能重叠的范围?

万修然
2023-03-14
问题内容

我有一个方法可以获取此类的许多对象

class Range<T>
{
    public T Start;
    public T End;
}

在我的情况下TDateTime,但int为了简单起见,请使用。我想要一种将这些范围折叠成覆盖相同“区域”但不重叠的方法。

所以如果我有以下范围

  • 1到5
  • 3至9
  • 11至15
  • 12至14
  • 13至20

该方法应该给我

  • 1至9
  • 11至20

猜猜它会被称为工会吗?我想方法签名可能看起来像这样:

public static IEnumerable<Range<T>> Collapse<T>(
    this IEnumerable<Range<T>>, 
    IComparable<T> comparer)
{
    ...
}

我在这里查看了一些其他类似的问题,但尚未找到该问题的实现。和其他相同问题的答案描述了算法,但是我不确定我是否理解算法。也不是特别擅长实现算法,所以我希望这里有人可以帮助我。


问题答案:

这似乎可行并且很容易理解。

    public static IEnumerable<Range<T>> Collapse<T>(this IEnumerable<Range<T>> me, IComparer<T> comparer)
    {
        List<Range<T>> orderdList = me.OrderBy(r => r.Start).ToList();
        List<Range<T>> newList = new List<Range<T>>();

        T max = orderdList[0].End;
        T min = orderdList[0].Start;

        foreach (var item in orderdList.Skip(1))
        {
            if (comparer.Compare(item.End, max) > 0 && comparer.Compare(item.Start, max) > 0)
            {
                newList.Add(new Range<T> { Start = min, End = max });
                min = item.Start;
            }
            max = comparer.Compare(max, item.End) > 0 ? max : item.End;
        }
        newList.Add(new Range<T>{Start=min,End=max});

        return newList;
    }

这是我在评论中提到的变体。基本上是同一回事,但是要进行一些检查和得出结果,而不是在返回之前将其收集在列表中。

    public static IEnumerable<Range<T>> Collapse<T>(this IEnumerable<Range<T>> ranges, IComparer<T> comparer)
    {
        if(ranges == null || !ranges.Any())
            yield break;

        if (comparer == null)
            comparer = Comparer<T>.Default;

        var orderdList = ranges.OrderBy(r => r.Start);
        var firstRange = orderdList.First();

        T min = firstRange.Start;
        T max = firstRange.End;

        foreach (var current in orderdList.Skip(1))
        {
            if (comparer.Compare(current.End, max) > 0 && comparer.Compare(current.Start, max) > 0)
            {
                yield return Create(min, max);
                min = current.Start;
            }
            max = comparer.Compare(max, current.End) > 0 ? max : current.End;
        }
        yield return Create(min, max);
    }


 类似资料:
  • 本文向大家介绍Bootstrap创建可折叠的组件,包括了Bootstrap创建可折叠的组件的使用技巧和注意事项,需要的朋友参考一下 本文将学习如何通过Bootstrap创建可折叠的组件,具体内容如下 什么是必需的 您必须引用 jquery.js 和 bootstrap-collapse.js - 这两个 JavaScript 文件都位于 docs/assets/js 文件夹内。 您可以在不编写大量

  • 主要内容:可折叠内容块,实例,实例,嵌套可折叠块,实例,可折叠集合,实例,更多实例可折叠内容块 可折叠块允许您隐藏或显示内容 - 对于存储部分信息很有用。 如需创建一个可折叠的内容块,需要为容器添加 data-role="collapsible" 属性。在容器(div)内,添加一个标题元素(H1-H6),后跟您想要进行扩展的 HTML 标记: 实例 <div data-role="collapsible"> <h1>点击我 - 我可以折叠!</h1> <p>我是可折叠的内容。<

  • 可折叠内容块 可折叠块允许您隐藏或显示内容 - 对于存储部分信息很有用。 如需创建一个可折叠的内容块,需要为容器添加 data-role="collapsible" 属性。在容器(div)内,添加一个标题元素(H1-H6),后跟您想要进行扩展的 HTML 标记: <div data-role="collapsible"> <h1>点击我 - 我可以折叠!</h1> <p>我是可折叠的内容。</

  • 要创建一个可折叠的区块,先创建一个容器,然后给容器添加data-role="collapsible"属性 容器内直接的标题(h1-h6)子结点,Jquery Mobile会将之表现为可点击的按钮,并在左侧添加一个“+"按钮,表示是可以展开的 在头部后面你可以添加任何想要折叠的html标记。框架会自动把这些标记包裹在一个容器里用以折叠或显 <div data-role="collapsible">

  • 问题内容: 我有一个具有以下结构的表:ID,Month,Year,Value,每个ID每个月一个条目的值,大多数月份都具有相同的值。 我想为该表创建一个视图,该视图折叠如下所示的相同值:ID,开始月,结束月,开始年,结束年,值,每个值每个ID一行。 要注意的是,如果值发生变化然后又回到原始值,则表中应该有两行 所以: 100 1 2008 80 100 2 2008 80 100 3 2008 9

  • 问题内容: 我已经看到了许多解决方案来识别日期范围重叠的记录,还有其他一些合并重叠范围的示例。 但是,我对显示仅重叠发生范围的结果感兴趣。实际上,我有3个ProductID(并且只有3个将存在),并且我试图为每个客户查找所有3个日期的日期范围。 问题答案: 答案如下: 这是使用自连接来计算每个产品上不同产品的数量。您需要三种截然不同的产品,因此该子句正在执行此操作。 有三种截然不同的产品,直到其中

  • 是否可以在Visual Studio代码中自定义代码折叠的工作方式? 我使用一种通用模式来定义各种不同文档类型之间的代码区域。 > 所以,对于XML,我用和包装文本部分 对于typescript/JavaScript,我使用和。 在完整的Visual Studio(不是VS代码)中,我有一个自定义扩展,它可以窥探文档类型之间的模式,并基于该模式创建折叠,从而允许我创建整洁的自定义文档大纲。我希望在

  • Collapsibles 是可折叠元素,扩大时,点击。他们允许您隐藏不立即与用户相关的内容。 气孔 创建一个气孔式可折叠组件,只要增加类 popout。 <ul class="collapsible popout" data-collapsible="accordion"> 可折叠组件的 HTML 结构 <ul class="collapsible" data-collapsible="accor