Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:组合相邻范围_C#_Algorithm_Generics_Range - Fatal编程技术网

C#:组合相邻范围

C#:组合相邻范围,c#,algorithm,generics,range,C#,Algorithm,Generics,Range,作为这个方法的后续,我想我会尝试创建一个结合相邻范围的方法 基本上,在运行Collapse方法之后,您可能会得到例如1到5和6到10。我想把它们合并成一个范围,1到10 这是我到目前为止提出的方法,但效果并不太好。有人发现我的问题或有好的替代方案吗 public static IEnumerable<Range<T>> MergeAdjacent<T>(this IEnumerable<Range<T>> source, Fun

作为这个方法的后续,我想我会尝试创建一个结合相邻范围的方法

基本上,在运行Collapse方法之后,您可能会得到例如1到5和6到10。我想把它们合并成一个范围,1到10

这是我到目前为止提出的方法,但效果并不太好。有人发现我的问题或有好的替代方案吗

    public static IEnumerable<Range<T>> MergeAdjacent<T>(this IEnumerable<Range<T>> source, Func<T, T, bool> isAdjacent)
    {
        using (var sourceIterator = source.GetEnumerator())
        {
            if (!sourceIterator.MoveNext())
                yield break;

            var first = sourceIterator.Current;

            while (sourceIterator.MoveNext())
            {
                var second = sourceIterator.Current;

                if (isAdjacent(first.End, second.Start))
                {
                    yield return Range.Create(first.Start, second.End);
                }
                else
                    yield return first;

                first = second;
            }

            yield return first;
        }
    }
publicstatic IEnumerable合并相邻(此IEnumerable源,Func为相邻)
{
使用(var sourceIterator=source.GetEnumerator())
{
如果(!sourceIterator.MoveNext())
屈服断裂;
var first=sourceIterator.Current;
while(sourceIterator.MoveNext())
{
var second=sourceIterator.Current;
if(i相邻(first.End,second.Start))
{
收益率返回范围.Create(first.Start,second.End);
}
其他的
收益率优先;
第一=第二;
}
收益率优先;
}
}

它将只合并两个相邻的范围,而不是三个或更多。保留最后一个,直到你找到一个缺口或列表的末尾

public static IEnumerable<Range<T>> MergeAdjacent<T>(this IEnumerable<Range<T>> source, Func<T, T, bool> isAdjacent)
{
    Range<T> current = null;

    foreach (Range<T> item in source)
    {
        if (current == null)
        {
            current = item;
        }
        else
        {
            if (isAdjacent(current.End, item.Start))
            {
                current = Range.Create(current.Start, item.End);
            }
            else 
            {
                yield return current;
                current = item;
            }
        }
    }

    if (current != null) 
        yield return current;
}
publicstatic IEnumerable合并相邻(此IEnumerable源,Func为相邻)
{
量程电流=零;
foreach(源中的范围项)
{
如果(当前==null)
{
当前=项目;
}
其他的
{
if(IsAjacent(current.End,item.Start))
{
当前=范围.Create(current.Start,item.End);
}
其他的
{
产生回流电流;
当前=项目;
}
}
}
如果(当前!=null)
产生回流电流;
}

我已经找到了这个解决方案。一个先决条件是根据Func对范围进行升序/降序排序。它将合并相邻的范围,但仍然延迟执行。我没有执行很多测试,所以可能会有一些边缘案例破坏了这一点。非犹太人:-)

编辑:将代码缩短一点。就我所知,它是有效的。忽略
null
检查

    public static IEnumerable<Range<T>> MergeAdjacent<T>(this IEnumerable<Range<T>> source, Func<T, T, bool> isAdjacent)
    {
        using (var it = source.GetEnumerator())
        {
            if (!it.MoveNext())
                yield break;

            var item = it.Current;

            while (it.MoveNext())
                if (isAdjacent(item.End, it.Current.Start))
                {
                    item = Range.Create(item.Start, it.Current.End);
                }
                else
                {
                    yield return item;
                    item = it.Current;
                }

            yield return item;
        }
    }
publicstatic IEnumerable合并相邻(此IEnumerable源,Func为相邻)
{
使用(var it=source.GetEnumerator())
{
如果(!it.MoveNext())
屈服断裂;
var item=it.Current;
while(it.MoveNext())
if(IsAjacent(item.End,it.Current.Start))
{
item=Range.Create(item.Start、it.Current.End);
}
其他的
{
收益回报项目;
项目=it.Current;
}
收益回报项目;
}
}

static void Main(字符串[]args)
{
变量范围=新列表
{
创建范围(1,3),创建范围(4,5),创建范围(7,10),
范围创建(11,17),范围创建(20,32),范围创建(33,80),
范围。创建(90100),
};
foreach(ranges.mergenextendent中的变量范围((r1,r2)=>r1+1==r2))
控制台写入线(范围);
}
//结果:1-5,7-20,25-80,90-100

@Svish,你检查过我的解决方案了吗?这不是你想要的吗?我还没有测试任何答案。星期一我回去上班时我会做什么?)是最后一次休息真的有必要吗?最后使用了这个,但稍微缩短了一点。
    static void Main(string[] args)
    {
        var ranges = new List<Range<int>>
        {
            Range.Create(1,3), Range.Create(4,5), Range.Create(7,10), 
            Range.Create(11,17), Range.Create(20,32), Range.Create(33,80), 
            Range.Create(90,100), 
        };

        foreach (var range in ranges.MergeAdjacent((r1, r2) => r1 + 1 == r2))
            Console.WriteLine(range);
    }

    // Result: 1-5, 7-20, 25-80, 90-100