C#:如何在具有许多条件(过滤器和项目组)的列表上进行迭代[处于保留状态]

问题描述 投票:-2回答:4

假设我有以下整数列表:

var numbers = new List<int> { 0, 0, 0, 27, 29, 24, 35, 33, 32, 1, 1, 1, 22, 55,
    44, 44, 55, 59, 0, 0, 0, 0 };

我想实现以下描述的搜索算法。我正在寻找数字59。

  1. 某些未指定的条件确定我是从左侧还是从右侧进行迭代。在此示例中,假设从左到右是迭代的方向。
  2. 我们需要修剪列表的开头:
    • 2.1。前导0应该忽略。
    • 2.2。如果下一项具有相同的十位数,则将它们分组在一起。例如,将27、29、24分组在一起。接下来,将35、33、32分组在一起。接下来,55.等
    • 2.3。如果该组包含一个偶数,它将被忽略,然后继续进行下一个直到找到仅包含奇数的一个。该组也将被忽略,我们继续执行此算法的第3步。
    • 2.3。 1也将被忽略。
  3. 一旦清除列表的开头,我们需要处理其余项目的结尾(44, 44, 55, 59, 0, 0, 0, 0):
    • 3.1。我们正在寻找第一个包含以9结尾的项目的组。我们返回该项目。返回59。如果我们从另一个方向进行迭代,则会发现29个。

我将如何在C#中实现此算法?这些是我的一些担忧:

  • 我可以使用whilefor构造来迭代整个列表,但是有时我不得不从列表的末尾开始这一事实将导致索引混乱。我曾考虑过实现自定义IEnumerable/IEnumerator来掩盖这种混乱,但是在这种情况下,我应该使用foreach语句。但是,当我尝试处理此foreach中上述的组时,我仍然会感到一团糟。
  • 我应该如何迭代列表并同时建立这些组。用C#做到这一点的干净方法是什么?
  • 出于效率的考虑,我们不应该进行第一遍从列表中滤除所有0的操作。在示例中,列表可以是一个非常长的10000000000元素列表的开始。如果我们要查找的数字是15,则无需检查9918477th元素。
  • 此外,此算法有2个不同的部分(序列的开头和结尾)。我不知道如何在一次迭代中同时处理它们。
  • 注意:此示例不是家庭作业。这是一个简化的问题,旨在消除涉及复杂对象和条件的实际问题的不必要的细节。

假设我有以下整数列表:var number = new List {0,0,0,27,29,24,35,33,32,1,1,1,22,55,44,44 ,55,59,0,0,0,0};我想实现搜索算法...

c# algorithm conditional-statements
4个回答
1
投票

如果您熟悉LINQ,并且很容易编写未内置的LINQ方法,则此问题非常容易。

using System.Linq;

var source = new List<int> { 0, 0, 0, 27, 29, 24, 35, 33, 32, 1, 1, 1,
    22, 55, 44, 44, 55, 59, 0, 0, 0, 0 };

var result = source
    .SkipWhile(n => n == 0) // Leading 0s ignored
    .GroupConsecutiveByKey(n => n / 10) // Next items having same tens grouped
    .SkipWhile(g => g.Any(n => n % 2 == 0)) // Group containing an even number ignored
    .Skip(1) // Next group ignored
    .Where(g => !g.All(n => n == 1)) // 1s are ignored as well
    .FirstOrDefault(g => g.Any(n => n % 10 == 9)) // Contains item ending in 9
    .FirstOrDefault(n => n % 10 == 9); // Item ending in 9

Console.WriteLine($"Result: {result}");

0
投票

您可以使用Linq,并进行一些自定义。您将需要实现一个反向枚举器,以便您可以使主要逻辑保持不变,而不管您是从左向右进行迭代,还是从左向右进行迭代。不要在大列表中使用Linq的Reverse方法,因为它会首先迭代整个集合。


0
投票

假设您有此列表:

var numbers = new List<int> { 0, 0, 0, 27, 29, 24, 35, 33, 32, 1, 1, 1, 55, 44, 44, 55, 59, 0, 0, 0, 0 };

0
投票

@@ Theodor Zoulias使用LINQ给出了答案。

以下解决方案是更手动的:

© www.soinside.com 2019 - 2024. All rights reserved.