在c#中查找两个列表之间的重叠

时间:2015-07-14 09:03:29

标签: c# matlab overlap

我有一个matlab代码,用于计算两个列表的重叠。实际上,它检查列表H是否在另一个列表U内,并且保持列表H在其中的列表H的窗口(至少一次)。事实上,U,H是Nx2大小的索引列表,其中在每个点中,窗口的开始索引和窗口的结束索引有两个值。我在matlab中的代码是:

function W = getwindowsspecial(U,H)
W = [];
for i = 1:size(U,1)
  if any(H(:,1)>=U(i,1) & H(:,1)<=U(i,2))
    W = [W;U(i,:)];
  end
end

例如U可能是:

54  86
112 217
292 325
402 451
628 664

H可能是:

129 214
297 321
406 447
637 664

,结果W是:

112 217
292 325
402 451

我想将该代码转换为c#。我的列表U,H是列表&gt;&gt;。我的对应功能如下:

 static List<int> getWindows(List<List<int>> list1, List<List<int>> list2)
    {
        List<int> list3 = new List<int>();

        for (int index = 0; index < list1[0].Count; index++) { 

        }

            return list3;
    }

为了使用Matlab,我应该填写什么功能?

编辑:在此代码中,我添加了第一个和第二个列表的限制。如何将这些限制添加到元组而不是列表列表?

        List<List<int>> first = new List<List<int>>();
        List<List<int>> second = new List<List<int>>();
        first.Add(upFirst); first.Add(downFirst);
        second.Add(upSecond); second.Add(downSecond);

        getWindows(first, second);

upFirst和upSecond包含第一个和第二个列表的所有左边界限,downFirst和downSecond包含第一个和第二个列表的所有正确限制。我尝试使用以下代码来完成我的工作:

 for (int index = 0; index < upFirst.Count; index++){

            first.Add(new List<int> { upFirst[index], downFirst[index] });

 }

 for (int index = 0; index < upSecond.Count; index++){

           second.Add(new List<int> { upSecond[index], downSecond[index]});

  }
  List<List<int>> lista = GetWindows(first, second);

这是我尝试添加为元组的内容。但是使用作为功能 @M。 Nasser Javaid结果我得到了NULL。我提供第一个和第二个列表的输入是:enter image description here

2 个答案:

答案 0 :(得分:4)

您可以针对这两个列表执行一些LINQ查询。为了使它更容易阅读,我假设您有元组列表,即List<Tuple<int, int>> s,而不是列表列表。

var W = U.Where(u => H.Any(h => h.Item1 >= u.Item1 && h.Item1 <= u.Item2));

请注意,这会复制MATLAB示例中的逻辑,但不会提供您在示例中指定的结果。如果要复制样本,请将第二个条件更改为h.Item2 < u.Item2,即从H查看元素的结尾,并要求严格的不等式。

Tuple s vs List s

如果Tuple<int,int>感到奇怪,请不要担心 - 它们很容易构建:

var t = Tuple.Create(2, 3);

根据您从哪里获取数据,这不应该是麻烦的。但是,如果您已将数据设为List<List<int>>,则可以轻松更改条件以使用h[0]代替h.Item1等。

我建议元组的主要原因是它们会更有效率,特别是如果您的矩阵UH中有很多行。

答案 1 :(得分:3)

请试试这个。根据给定的场景,我们需要来自U的数字,它们在H的范围内,因此它们是......

public void Test()
    {
        var listU = new List<List<int>>
        {
            new List<int> {54, 86},
            new List<int> {112, 217},
            new List<int> {292, 325},
            new List<int> {402, 451},
            new List<int> {628, 664}
        };
        var listH = new List<List<int>>
        {
            new List<int> {129, 214},
            new List<int> {297, 321},
            new List<int> {406, 447},
            new List<int> {637, 664}
        };
        GetWindows(listU, listH);
    }

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        List<List<int>> list3 = new List<List<int>>();
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        foreach (var num in listU)
        {
            var initial = num[0];
            var final = num[num.Count - 1];
            if (initial > startingOfH && final < endOfH)
            {
                list3.Add(num);
            }
        }
        return list3;
    }

编辑: 如果您想使用Linq,请使用此

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        return (from num in listU 
                let initial = num[0] 
                let final = num[num.Count - 1] 
                where initial > startingOfH && final < endOfH 
                select num).ToList();
    }

编辑2: 忽略初始值

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        List<List<int>> list3 = new List<List<int>>();
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        foreach (var num in listH)
        {
            var final = num[num.Count - 1];
            if (final > startingOfH && final < endOfH)
            {
                list3.Add(num);
            }
        }
        return list3;
    }

如果你喜欢Linq那么

static List<List<int>> GetWindows(List<List<int>> listU, List<List<int>> listH)
    {
        var startingOfH = listH.First()[0];
        var endOfH = listH.Last()[listH.Last().Count - 1];
        return (from num in listH 
                let final = num[num.Count - 1] 
                where final > startingOfH && final < endOfH 
                select num).ToList();
    }