如何在 C# 中比较相邻的双端队列元素?

How to compare adjacent deque elements in C#?

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

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

在 post (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 库,所以我目前正在寻找类似的技术实现相同的解决方案。

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

有什么建议

你可以这样试试:

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

您可以像这样自己实现 python 成对方法:

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();
}

只需创建函数:

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}");
}

一个名为 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;
                }
            }
        }
    }

唯一的"trick"是使用名为...的局部迭代器函数_

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

这个表达式:

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

生成以下数组:

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