Как найти список (Of Byte) для двух значений с помощью Framework? - PullRequest
0 голосов
/ 23 марта 2009

Есть ли способ поиска в списке по нескольким последовательным значениям? Я смотрю на Find и IndexOf, но Find использует предикаты, которые используют только текущее значение, а IndexOf принимает только байтовые параметры.

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

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 23 марта 2009

Одной из идей может быть разделение вашего списка на группы последовательных значений, а затем сравнение содержимого каждого из них. Вот еще одна функция (взята из базовой библиотеки F #), которая будет выполнять разбиение.

static IEnumerable<T[]> Windowed<T>(this IEnumerable<T> source, int size)
{
  if (source == null)
    throw new NullReferenceException();
  if (size <= 0)
    throw new ArgumentOutOfRangeException("size", "The window size must be positive.");

  var arr = new T[size];
  var r = size-1;
  var i = 0;
  foreach (T item in source)
  {
    arr[i] = item;
    i = (i+1) % size;
    if (r == 0)
    {
      var res = new T[size];
      for (int j = 0; j < size; j++)
        res[j] = arr[(i+j) % size];
      yield return res;
    }
    else 
      r -= 1;
  }
}

Вы можете использовать вышеуказанную функцию следующим образом:

var result = Enumerable.Range(1, 10).Windowed(2)
               .Where(a => a[0] == 3 && a[1] == 4)
               .First();
0 голосов
/ 23 марта 2009

Это моё собственное решение вопроса. Мне нравится метод, потому что он может обрабатывать любое количество элементов, это O (n) и он довольно прост:

    <Extension()> Public Function Find(Of T)(ByVal list As List(Of T), ByVal searchedValue As T(), ByVal startingIndex As Integer) As Integer
    Dim mainIndex As Integer
    Dim searchedIndex As Integer
    Dim result As Integer

    result = -1 ' Initialize result
    mainIndex = startingIndex

    While mainIndex < list.Count AndAlso result = -1
        If list(mainIndex).Equals(searchedValue(0)) Then
            searchedIndex = 0
            While searchedIndex < searchedValue.Length AndAlso (list(mainIndex + searchedIndex).Equals(searchedValue(searchedIndex)))
                searchedIndex = searchedIndex + 1
            End While

            If searchedIndex = searchedValue.Length AndAlso list(mainIndex + searchedIndex - 1).Equals(searchedValue(searchedIndex - 1)) Then
                result = mainIndex
            End If
        End If

        mainIndex = mainIndex + 1
    End While

    Return result
End Function
0 голосов
/ 23 марта 2009

Я не думаю, что это особенно распространенная проблема, если честно - я почти уверен, что в рамках ничего нет.

Я подозреваю, что вам нужно решить, хотите ли вы, чтобы эффективность или простота реализовывали ваши собственные. Довольно простая версия метода расширения может выглядеть так:

public static int IndexOf<T>(this IEnumerable<T> source,
                             T first,
                             T second)
{
    IEqualityComparer<T> comparer = EqualityComparer<T>.Default;

    // We can only return when we've read source[index+1], so we need
    // to keep one value behind
    int index=-1;
    T prev = default(T);
    foreach (T element in source)
    {
        if (comparer.Equals(first, prev) &&
            comparer.Equals(second, element) &&
            index >= 0) // Avoid edge cases where first=default(T)
        {
            return index;
        }
        index++;
        prev = element;
    }
    return -1;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...