来自不同列表的元素的摘要,这些元素都彼此相关

Summary of elements from different lists, which are all related to each other

提问人:CShark 提问时间:10/15/2023 最后编辑:shingoCShark 更新时间:10/15/2023 访问量:64

问:

假设您有一个包含多个条目的 List<List> 实例。例如:

List<List<int>> inputLists = new List<List<int>>
{
    new List<int> { 4, 2, 1 },
    new List<int> { 5, 9, 1 },
    new List<int> { 6, 1, 2 },
    new List<int> { 9, 4, 3 },
    new List<int> { 9, 4, 2 }
};

我现在想在更大的列表中总结元素,如果每个元素都与每个元素相关。结果列表应至少包含 4 个元素。对于上面的示例,我们的结果将是一个 List<List>只有一个条目:{ 4, 2, 1, 9 }(排序无关紧要)。为什么?

尝试结对:

  • 9 与 1 位于同一列表中(检查第二个列表)
  • 9 与 2 位于同一列表中(最后检查)
  • 9 与 4 在同一个列表中(检查第四个/最后一个)
  • 4、2 和 1 也都在同一个列表中(先检查;微不足道)

这是我的代码。如果它出现脑损伤,我想道歉,我最近睡眠不足。

internal void Test()
{
    List<List<int>> inputLists = new List<List<int>>
{
    new List<int> { 4, 2, 1 },
    new List<int> { 5, 9, 1 },
    new List<int> { 6, 1, 2 },
    new List<int> { 9, 4, 3 },
    new List<int> { 9, 4, 2 }
};

    foreach (var input in inputLists)
    {
        IEnumerable<IEnumerable<int>> results = Array.Empty<IEnumerable<int>>();
        input.ForEach(number =>
        {
            //first step: getting all numbers that are related to "number"
            //number is 4 | related ones are: 4, 2, 1, 9, 3
            IEnumerable<int> everyFrickingNumberAppearing = Array.Empty<int>();
            inputLists.Where(inputList => inputList.Contains(number)).ToList()
            .ForEach(inputList =>
            everyFrickingNumberAppearing =   everyFrickingNumberAppearing.Concat(inputList).Distinct()
            );


            var IReallyDontKnowWhatIAmDoing = everyFrickingNumberAppearing
            //trying out every number
            .Where(probablyRelatedNumber => inputLists
            //looking if there is at least one element that
            //appears in at least one list together with "number"
            .Any(list => list.Contains(probablyRelatedNumber) && list.Contains(number)))
            .ToArray();
            //appending all related numbers of "number" to results
            results.Append(IReallyDontKnowWhatIAmDoing);
        });
        //going through results
        results.ToList().ForEach(r =>
        {
            //selecting only nums which appear in every result
            var importantNums = r.Select(num => results.ToList().All(l => l.Contains(num)));
            //print it
            importantNums.ToList().ForEach(n => Console.Write($"{n} "));
            Console.WriteLine();
        });
    }
}

如上所述,我预计 4 2 1 9(排序不相关)是输出。 谢谢你的帮助。

C# .NET 列出 LINQ 编号

评论

1赞 Auditive 10/15/2023
我认为你至少应该在描述中构建你的逻辑。然后,如果解决方案不会自行出现,也许问题会变得更加清晰。因为就目前而言,遵循您的想法很复杂,这是不相关的关系和未配对的数字对的混合,您想要关联或配对(通过...什么标准?
0赞 CShark 10/15/2023
我试着用不同的方式解释它。我们有几个小列表,并希望将它们总结为更大的列表。标准是列表中的每个元素已经成对出现在一个较小的列表中。
0赞 CShark 10/15/2023
另一个例子:{ 1, 2, 3 }, {4, 5, 1} {4, 2, 5}, {3, 7, 4} 将导致 {1, 2, 3, 4},因为这 4 个元素中的每一对都出现在一个较小的列表中。
0赞 shingo 10/15/2023
我觉得这很难理解。如果这是来自家庭作业或程序游戏,请出示原始描述。如果这是来自实际问题,请描述问题本身。
0赞 CShark 10/15/2023
它不是家庭作业或游戏。没有“原始”描述。我真的不知道如何用另一种方式解释它。你有几个列表。您可能会找到成对的数字。“对”由同一列表中的两个数字定义。我想总结所有成对的数字。反之亦然:如果我们得到结果 { 1, 2, 3},那么我们的输入一定是一堆列表,其中至少有一个包含对 { 1, 2 },其中一个包含对 { 2, 3 },其中一个包含对 { 1, 3 }。

答:

0赞 Olivier Jacot-Descombes 10/15/2023 #1

让我们创建一个存储,将每对数字作为值元组存储在同一个列表中。为简单起见,我们将配对存储两次为 (x, y) 和 (y, x)。这简化了进一步的处理。HashSet<(int, int)>

var pairs = new HashSet<(int, int)>();
foreach (var smallList in _inputLists) {
    foreach (int a in smallList) {
        foreach (int b in smallList) {
            if (a != b) {
                pairs.Add((a, b));
            }
        }
    }
}

由于每对出现两次,分别为 (x, y) 和 (y, x),我们现在可以简单地按元组 () 中的一个项目进行分组,并计算它发生的次数以过滤至少出现 4 次的项目。Item1

var result = pairs
    .Select(p => p.Item1)
    .GroupBy(x => x)
    .Where(g => g.Count() >= 4)
    .OrderBy(g => g.Key);
foreach (var g in result) {
    Console.WriteLine(g.Key);
}

指纹:

1
2
4
9

评论

0赞 CShark 10/15/2023
感谢您提供帮助。我们已经完成了一半。您的解决方案仅提供一种可能性,即使有更多列表要返回也是如此。我想剩下的就靠我自己了。