Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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#_Linq_Task Parallel Library_Intersection - Fatal编程技术网

C# 确定树列表中根数据的子集

C# 确定树列表中根数据的子集,c#,linq,task-parallel-library,intersection,C#,Linq,Task Parallel Library,Intersection,我的结构如下: Node { List<String> rootData; List<Node> Children; } 我需要的最终答案应该在一个新的列表中,包含: 1: {rootData: A, B, C, D} 2: {rootData: E, F, G} 这可以通过LINQ和TPL(或更有效的方式)来实现吗?我希望它是有效和正确的 编辑: 以下代码应该在所有情况下都正常工作,还是我遗漏了什么 lstOfTrees.Add(new node()

我的结构如下:

Node
{
    List<String> rootData;
    List<Node> Children;
}
我需要的最终答案应该在一个新的列表中,包含:

1: {rootData: A, B, C, D}
2: {rootData: E, F, G}
这可以通过LINQ和TPL(或更有效的方式)来实现吗?我希望它是有效和正确的

编辑:

以下代码应该在所有情况下都正常工作,还是我遗漏了什么

lstOfTrees.Add(new node());
lstOfTrees[0].rootData = new List<string> {"A", "B", "C", "D"};
lstOfTrees.Add(new node());
lstOfTrees[1].rootData = new List<string> {"E", "F", "G"};
lstOfTrees.Add(new node());
lstOfTrees[2].rootData = new List<string> {"G", "H"};
lstOfTrees.Add(new node());
lstOfTrees[3].rootData = new List<string> {"J", "A", "C"};
lstOfTrees.Add(new node());
lstOfTrees[4].rootData = new List<string> {"D", "Z"};


Dictionary<int,node> dictOfTrees_indexToNode = Enumerable.Range(0, lstOfTrees.Count).ToDictionary(x=>x,x => lstOfTrees[x]);

List<int> notToInclude = new List<int>();
for (int i = 0; i < lstOfTrees.Count; i++)
{
    for (int j = 0; j < lstOfTrees.Count; j++)
    {
        if (j != i)
        {
            if (!lstOfTrees[j].Equals(lstOfTrees[i]))
            {
                if (lstOfTrees[j].rootData.Join(lstOfTrees[i].rootData, root => root, innerRoot => innerRoot,
                                                (root, innerRoot) => 1).Any())
                {
                    bool test = (lstOfTrees[j].rootData.Count > lstOfTrees[i].rootData.Count);
                    notToInclude.Add(test ? i : j);
                }
            }
        }
    }
}

List<node> finalList = new List<node>();
finalList.AddRange(lstOfTrees.Except(notToInclude.Select(s=>dictOfTrees_indexToNode[s])));
添加(新节点()); lstOfTrees[0]。rootData=新列表{“A”、“B”、“C”、“D”}; 添加(新节点()); lstOfTrees[1].rootData=新列表{“E”、“F”、“G”}; 添加(新节点()); lstOfTrees[2].rootData=新列表{“G”,“H”}; 添加(新节点()); lstOfTrees[3].rootData=新列表{“J”、“A”、“C”}; 添加(新节点()); lstOfTrees[4].rootData=新列表{“D”,“Z”}; Dictionary dictOfTrees_indexToNode=Enumerable.Range(0,lstOfTrees.Count).ToDictionary(x=>x,x=>lstOfTrees[x]); 列表notToInclude=新列表(); for(int i=0;iroot,innerRoot=>innerRoot, (root,innerRoot)=>1.Any()) { bool test=(lstOfTrees[j].rootData.Count>lstOfTrees[i].rootData.Count); 注:增加(试验i:j); } } } } } List finalList=新列表(); AddRange(lstOfTrees.Except(notToInclude.Select(s=>dictOfTrees_indexToNode[s]));
另外,我可以从中改进吗?

我已经将测试的情况简化为只搜索字符串列表,这应该与您在一小步中间步骤后所做的相同:

var list = lstOfTrees.Select(x => new HashSet<string>(x.rootData)).ToList();
var list=lstOfTrees.Select(x=>newhashset(x.rootData)).ToList();
另外,在这里使用集合可能更好,至少我在示例数据中没有看到任何重复项,这是第二个更改

在这里使用集合是非常重要的,因此,如果数据实际上可以在列表中复制,那么整个解决方案将不得不改变

结果如下:

var list = new List<List<string>> {
        new List<string> {"A", "B", "C", "D"},
        new List<string> {"E", "F", "G"},
        new List<string> {"G", "H"},
        new List<string> {"J", "A", "C"},
        new List<string> {"D", "Z"}};

var sets = list.Select(x => new HashSet<string>(x)).ToList();

var result = sets.Select(x => sets.Where(y => x.Overlaps(y)) // You are looking not for 'subsets', but overlapping sets
                                  .OrderByDescending(y => y.Count)
                                  .FirstOrDefault())
                 .Distinct();
var list=新列表{
新名单{“A”、“B”、“C”、“D”},
新名单{“E”、“F”、“G”},
新列表{“G”,“H”},
新名单{“J”、“A”、“C”},
新名单{“D”、“Z”};
var set=list.Select(x=>newhashset(x)).ToList();
var result=sets.Select(x=>sets.Where(y=>x.Overlaps(y))//您找的不是“子集”,而是重叠集
.OrderByDescending(y=>y.Count)
.FirstOrDefault())
.Distinct();
这将返回
IEnumerable

{“A”、“B”、“C”、“D”}、{“E”、“F”、“G”}


在LINQPad中测试:)

1>没错,字符串在一个节点中是唯一的。2> 在对我的应用程序进行测试后,您会知道:)谢谢。(linqPad对我来说是新事物)
var list = lstOfTrees.Select(x => new HashSet<string>(x.rootData)).ToList();
var list = new List<List<string>> {
        new List<string> {"A", "B", "C", "D"},
        new List<string> {"E", "F", "G"},
        new List<string> {"G", "H"},
        new List<string> {"J", "A", "C"},
        new List<string> {"D", "Z"}};

var sets = list.Select(x => new HashSet<string>(x)).ToList();

var result = sets.Select(x => sets.Where(y => x.Overlaps(y)) // You are looking not for 'subsets', but overlapping sets
                                  .OrderByDescending(y => y.Count)
                                  .FirstOrDefault())
                 .Distinct();