Примечание;на момент написания этого ответа не было ясно, что обсуждаемые последовательности являются массивами char. Этот ответ дает более общий совет для коллекций строк или сложных типов. Для массивов char возможна конкретная оптимизация отсутствия строкового разделителя или использования строкового конструктора, который принимает массив char;другие ответы упоминают об этом, поэтому я не буду повторять это здесь
Не совсем уверен, как вы храните свои последовательности, но, надеюсь, они перечисляются в этом случае:
string.Join(",", haystackCollection).Contains(string.Join(",", needleCollection));
Я использовал запятую в качестве разделителя, но вы должны использовать символ, который никогда не встречается в реальных коллекциях
Более полный пример:
var haystackCollection = "XAZABCDEA".ToCharArray();
var needleCollection = "ABCD".ToCharArray();
bool result = string.Join(",", haystackCollection).Contains(string.Join(",", needleCollection));
Это надежно, только если ваши коллекции представляют собой строки одинаковой длины,Становится ненадежным, если в стоге сена могут содержаться строки различной длины, потому что в стоге сена {"AB","AC"}
нет иглы {"B","A"}
, но этот метод сообщает, что это так.
Вы можете сделать это лучше, поместив разделители в начале и конце каждого объединения строк, например:
string s = ",";
(s+string.Join(s, haystackCollection)+s).Contains(s+string.Join(",", needleCollection)+s);
Но в этот момент может быть лучше полностью переключить метод. Также, если вы хотите узнать индекс, он встречается немного сложнее, используя этот метод соединения строк, потому что вам придется использовать IndexOf, а затем многократно вычитать длины каждого элемента плюс разделитель, чтобы вернуться к индексу. Возможно, вам лучше использовать петли:
int idx = 0;
while(idx < haystack.Length){
if(haystack[idx] == needle[0]){
int i = 1;
while(haystack[idx+i] == needle[i] && i<needle.Length)
i++;
if(i == needle.Length)
return idx; // you found the start of the needle
}
idx++;
}
В этом последнем методе мы начинаем просматривать стог сена, пытаясь найти первый элемент иглы. Если мы найдем его, мы начнем цикл, который проверяет остальную часть иглы. Эта петля только удерживает гонг, пока он находит записи иголки в стоге сена. Если цикл останавливается досрочно, то индексная переменная i
не будет увеличиваться вплоть до длины массива игл, поэтому мы можем сделать вывод, что если переменная i
действительно равна длине иглы,игла была найдена в позиции idx
в стоге сена
Чтобы этот метод сработал, вам действительно нужно, чтобы ваши коллекции были индексируемыми с помощью Integer, а не просто перечислимыми, если только вы не хотите получить более запутанную. Помните, что если вы используете List вместо Array, то это Count, а не Length