Найти массив (byte []) внутри другого массива? - PullRequest
6 голосов
/ 01 февраля 2011

Какой самый простой способ найти байт [] внутри другого байта []? У меня такое чувство, что я могу сделать это с помощью linq, но я не знаю как.

Примечание: я выполнил поиск с [c#] и ничего не нашел, я удивлен.

Ответы [ 4 ]

18 голосов
/ 12 ноября 2014

Вот более быстрая версия Отличный ответ Эргвуна :

static int SearchBytes( byte[] haystack, byte[] needle ) {
    var len = needle.Length;
    var limit = haystack.Length - len;
    for( var i = 0;  i <= limit;  i++ ) {
        var k = 0;
        for( ;  k < len;  k++ ) {
            if( needle[k] != haystack[i+k] ) break;
        }
        if( k == len ) return i;
    }
    return -1;
}

В кратком тесте со стогом сена 11 МБ и иглой 9 байтов это было примерно в три раза быстрее.

Оптимизация:

  • Нет вызова функции каждый раз через внешний цикл.
  • Кэшируется длина иглы и предел поиска.
  • Удалено избыточное испытание длины в начале match().

Конечно, для длинных байтовых массивов вы хотели бы использовать что-то вроде поиска Бойера-Мура, но для многих целей простой алгоритм, подобный этому, достаточно хорош, и он имеет преимущество в том, что он короткий и легкий для понимания и проверки. .

8 голосов
/ 01 февраля 2011

Вот простой (наивный?) Способ сделать это:

static int search(byte[] haystack, byte[] needle)
{
    for (int i = 0; i <= haystack.Length - needle.Length; i++)
    {
        if (match(haystack, needle, i))
        {
            return i;
        }
    }
    return -1;
}

static bool match(byte[] haystack, byte[] needle, int start)
{
    if (needle.Length + start > haystack.Length)
    {
        return false;
    }
    else
    {
        for (int i = 0; i < needle.Length; i++)
        {
            if (needle[i] != haystack[i + start])
            {
                return false;
            }
        }
        return true;
    }
}
0 голосов
/ 14 декабря 2012

Попробуйте это с использованием лямбда-выражений:

private bool CheckPatternInArray(byte[] array, byte[] pattern)
{
    int fidx = 0;
    int result = Array.FindIndex(array, 0, array.Length, (byte b) =>
            {
                fidx = (b == pattern[fidx]) ? fidx + 1 : 0;
                return (fidx == pattern.Length);
            });
    return (result >= pattern.Length - 1);
}

Если вам нужен самый быстрый, проверьте решения здесь .

0 голосов
/ 01 февраля 2011

Вы, наверное, могли бы это понять сами, но иногда мне нравится делать простую вещь.

bool found = false;
int i = 0;
for(; i < byteArray.Length || found; i++)
{
  if(byteArray[i] == lookingFor)
  {
    found = true;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...