Как сравнить соседние элементы deque в C #? - PullRequest
1 голос
/ 01 октября 2019

Я пытаюсь перенести некоторый код с Python на C #.

Цель состоит в том, чтобы сравнить соседние элементы и посмотреть, больше ли четыре последовательных значения, чем одно другое.

После этого поста ( Сравнить два смежных элемента в одном и том же списке ) Мне удалось использовать попарно на деке для успешного сравнения смежных элементов .

//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 , поэтому в настоящее время я ищу подобный метод для достижения того же решения.

FYI. Реализация deque от https://www.nuget.org/packages/Nito.Collections.Deque/

Любые предложения ?

Ответы [ 4 ]

1 голос
/ 01 октября 2019

Там - это проект под названием 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 в качестве оптимизированного оператора Window только для 2 элементов. Есть еще один оператор Window , который может возвращать последовательности из N элементов.

Это выражение:

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

Создает следующие массивы:

{1,2,3}
{2,3,4}
{3,4,5}
1 голос
/ 01 октября 2019

Вы можете самостоятельно реализовать попарный метод 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();
}
1 голос
/ 01 октября 2019

Просто создайте функцию:

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}");
}
0 голосов
/ 01 октября 2019

Вы можете попробовать вот так:

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