【问题标题】:How to compare adjacent deque elements in C#?如何在 C# 中比较相邻的双端队列元素?
【发布时间】:2019-10-01 10:41:28
【问题描述】:

我正在尝试将一些代码从 Python 移植到 C#。

目标是比较相邻的元素,看看四个连续的值是否大于另一个。

在这篇文章 (Compare two adjacent elements in same list) 之后,我能够在 deque 上使用 pairwise 来成功地比较相邻元素

//In python
from more_itertools import pairwise

for x, y in pairwise(a_deque):
    if (x < y):
        i += 1
        if (i == 4)
            print("Hello world!")

问题在于 C# 不包含 more_itertools 库,因此我目前正在寻找一种类似的技术来实现相同的解决方案。

仅供参考。 deque 实现来自https://www.nuget.org/packages/Nito.Collections.Deque/

有什么建议

【问题讨论】:

    标签: c# python loops porting deque


    【解决方案1】:

    你可以像这样自己实现python pairwise方法:

    public static IEnumerable<(T, T)> Pairwise<T>(IEnumerable<T> collection)
    {
        using (var enumerator = collection.GetEnumerator())
        {
            enumerator.MoveNext();
            var previous = enumerator.Current;
            while (enumerator.MoveNext())
            {
                yield return (previous, enumerator.Current);
                previous = enumerator.Current;
            }
        }
    }
    

    那么c#中的算法在结构上与python版本非常相似:

    static void Main(string[] args)
    {
        var values = new[] { 5, 7, 8, 9, 10, 10, 8, 2, 1 };
    
        var i = 0;
    
        foreach (var (x, y) in Pairwise(values))
        {
            if (x < y)
            {
                i++;
                if (i == 4)
                    Console.WriteLine("Hello world!");
            }
        }
    
        Console.ReadLine();
    }
    

    【讨论】:

      【解决方案2】:

      一个名为MoreLINQ 的项目,带有巧妙的 LINQ 扩展。大多数时候,由于 LINQ 的简单性,代码非常简单。您可以将其添加为 NuGet 包或仅添加所需运算符的单个源包。

      Pairwise.cs 实现了一个可以将函数应用于元素对的运算符:

      int[] numbers = { 123, 456, 789 };
      var result = numbers.Pairwise((a, b) => a + b);
      

      来源非常简单——检索一个项目,如果我们还没有到达终点,检索另一个并应用函数:

          public static IEnumerable<TResult> Pairwise<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TSource, TResult> resultSelector)
          {
              if (source == null) throw new ArgumentNullException(nameof(source));
              if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
      
              return _(); 
      
              IEnumerable<TResult> _()
              {
                  using (var e = source.GetEnumerator())
                  {
                      if (!e.MoveNext())
                          yield break;
      
                      var previous = e.Current;
                      while (e.MoveNext())
                      {
                          yield return resultSelector(previous, e.Current);
                          previous = e.Current;
                      }
                  }
              }
          }
      

      唯一的“技巧”是使用名为 ..._ 的本地迭代器函数

      您可以将 Pairwise 运算符视为仅针对 2 个项目的优化 Window 运算符。 还有另一个Window 运算符可以返回N 个项目的序列。

      这个表达式:

      var x=Enumerable.Range(1,5).Window(3);
      

      产生以下数组:

      {1,2,3}
      {2,3,4}
      {3,4,5}
      

      【讨论】:

        【解决方案3】:

        只需创建函数:

        static IEnumerable<(T, T)> PairWise<T>(IEnumerable<T> collection)
        {
            var queue = new Queue<T>();
        
            foreach (T item in collection)
            {
                queue.Enqueue(item);
        
                if (queue.Count == 2)
                {
                    T x = queue.Dequeue();
                    T y = queue.Peek();
                    yield return (x, y);
                }
            }
        }
        

        并使用它:

        foreach ((int x, int y) in PairWise(new[] {1, 2, 3, 4, 5}))
        {
            Console.WriteLine($"{x} {y}");
        }
        

        【讨论】:

        • 那不编译是吗?我认为您不能像在使用时那样将元组解构与元组变量一起使用。
        • 我忘了删除“元组”这个词。现在应该编译成功了。
        【解决方案4】:

        你可以这样尝试:

        for (int i = 0; i < arr.Length - 1; ++i)
        {
            int a = arr[i];
            int b = arr[i + 1];
            Console.WriteLine($"{a} {b}");
        }
        

        【讨论】:

          猜你喜欢
          • 2012-07-24
          • 1970-01-01
          • 2012-05-04
          • 1970-01-01
          • 2019-05-05
          • 2021-04-28
          • 2020-08-05
          • 2020-04-24
          • 2014-06-22
          相关资源
          最近更新 更多