Capisco che questo è una vecchia questione, ma avevo bisogno di questo metodo esatto e l'ho scritto in questo modo:
public static int ContainsSubsequence<T>(this IEnumerable<T> elements, IEnumerable<T> subSequence) where T: IEquatable<T>
{
return ContainsSubsequence(elements, 0, subSequence);
}
private static int ContainsSubsequence<T>(IEnumerable<T> elements, int index, IEnumerable<T> subSequence) where T: IEquatable<T>
{
// Do we have any elements left?
bool elementsLeft = elements.Any();
// Do we have any of the sub-sequence left?
bool sequenceLeft = subSequence.Any();
// No elements but sub-sequence not fully matched
if (!elementsLeft && sequenceLeft)
return -1; // Nope, didn't match
// No elements of sub-sequence, which means even if there are
// more elements, we matched the sub-sequence fully
if (!sequenceLeft)
return index - subSequence.Count(); // Matched!
// If we didn't reach a terminal condition,
// check the first element of the sub-sequence against the first element
if (subSequence.First().Equals(e.First()))
// Yes, it matched - move onto the next. Consume (skip) one element in each
return ContainsSubsequence(elements.Skip(1), index + 1 subSequence.Skip(1));
else
// No, it didn't match. Try the next element, without consuming an element
// from the sub-sequence
return ContainsSubsequence(elements.Skip(1), index + 1, subSequence);
}
Aggiornato non solo di ritorno se il sub-sequenza abbinato, ma dove ha cominciato a la sequenza originale.
Questo è un metodo di estensione su IEnumerable, completamente pigro, viene terminato anticipatamente ed è molto più lineare rispetto alla risposta attualmente votata. Bewarned, tuttavia (come indicato da @ wai-ha-lee), lo è ricorsivo e crea un lotto di enumeratori. Usalo laddove applicabile (prestazioni/memoria). Questo andava bene per i miei bisogni, ma YMMV.
Quanto è grande largeSequence? E questo è per uso pratico o concettuale? Perché posso pensare a un paio di modi che andrebbero bene su un record relativamente piccolo (poche migliaia), ma non sarebbe necessariamente bello o lavorare in ambienti più grandi. –
Preferirei qualcosa che si adattasse bene con sequenze di grandi dimensioni, L'applicazione effettiva è piccola (solo poche centinaia di elementi), tuttavia andrà nella nostra classe di utilità, quindi potrebbe essere utilizzata per sequenze molto più grandi in futuro. – trampster
Cosa ti aspetti che venga restituito FindSequence? Un indice? Vero falso? La sotto-sequenza? Gli elementi da abbinare devono essere tutti in ordine e adiacenti? –