2013-06-02 2 views
1

У меня есть несколько массивов, заполненных 1 и 0. Есть ли простой способ найти, например, 10 полей рядом друг с другом со значением 1?C# - Поиск последовательностей в массивах

Что-то вроде: if (array [i ... i + 10] = 1) -> сделать что-нибудь?

Я знаю, что могу использовать for, но у меня огромный массив, и это очень полезно.

+0

Если вы хотите иметь быстрое время поиска без прокрутки, возможно, закодировать информацию в вашем массиве из get-go. Вместо сохранения массива с '1' и' 0', сохраните его как набор объектов 'Sequence', которые имеют такие свойства, как' Value' (которые будут хранить '1' или' 0') и 'Length' (что укажите, сколько из этого значения дублируется в строке). Тогда было бы гораздо быстрее перепрыгнуть через ваш массив, по одной полной последовательности за раз. Можно даже поместить эти последовательности в упорядоченную таблицу поиска (возможно, по 'Length'). –

ответ

7

Вы можете сделать это довольно легко с циклом:

int c = 0; 
for (int i = 0; i < myArray.Length; i++) 
{ 
    c = (myArray[i] == 1) ? c + 1 : 0; 
    if (c >= 10) 
    { 
     // do stuff 
    } 
} 

Вот еще один способ с помощью Linq:

var indexes = 
    from i in Enumerable.Range(0, myArray.Length - 10) 
    where myArray.Skip(i).Take(10).All(x => x == 1) 
    select i; 
foreach(var i in indexes) 
{ 
    // do stuff 
} 

Это возвращает все индексы myArray где элемент по этому индексу а элементы, следующие 9 индексов, равны 1. Однако этот метод несколько менее эффективен, чем простой цикл for, поскольку он потенциально проверяет каждый элемент более одного раза.

Если вы предпочитаете свободно синтаксис:

var indexes = Enumerable.Range(0, myArray.Length - 10) 
         .Where(i => myArray.Skip(i).Take(10).All(x => x == 1)); 
foreach(var i in indexes) 
{ 
    // do stuff 
} 
+0

Привет. это было приятное объяснение. Но я сомневаюсь, что вы можете уточнить? Я предполагаю, что в массиве 12 элементов, тогда диапазон занял 2 (12-10) позиций. В том месте, где вы помещаете переменную «i» в пропуске, так что я думаю, что значение «i» равно 1 и 2. Как он достигнет 10-й позиции? Извините, если это очень просто. – Smaug

+0

@ RameshMuthiah Это не так. В решении Linq я рассматриваю только 'i' в' [0, length-10] '. Но затем он тестирует 'i' и следующие 9 элементов, поэтому каждый элемент get проверяется (хотя бы один раз). –

+0

int [] value = new int [] {10,20,31,40,51,60,1,0,1,1,122,100,12,10,11}; var result = from i in Enumerable.Range (0, value.Length - 10) где value.Skip (i) .Take (10) .All (X => X == X) select value [i] ; – Smaug

1

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

Существует много алгоритмов. Первой отправной точкой является this page here

Из алгоритмов Turbo-Boyer-Moore является наиболее эффективным.

Но вы также можете справиться с этой проблемой со структурой данных, как дерево суффиксов: see this article on suffix trees (or simply called Trie)

Вот реализация алгоритма Бойера-Мура Codeproject article on Boyer-Moore

Смежные вопросы