我需要找到其他大序列的序列,例如,{1,3,2,4,3}和{5,1,3中存在{1,3} }.有没有办法快速使用IEnumerable或其他东西?
解决方法
此方法将在父序列中找到可通过Equals()进行比较的任何类型的子序列:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent,IEnumerable<T> target) { bool foundOneMatch = false; using (IEnumerator<T> parentEnum = parent.GetEnumerator()) { using (IEnumerator<T> targetEnum = target.GetEnumerator()) { // Get the first target instance; empty sequences are trivially contained if (!targetEnum.MoveNext()) return true; while (parentEnum.MoveNext()) { if (targetEnum.Current.Equals(parentEnum.Current)) { // Match,so move the target enum forward foundOneMatch = true; if (!targetEnum.MoveNext()) { // We went through the entire target,so we have a match return true; } } else if (foundOneMatch) { return false; } } return false; } } }
你可以像这样使用它:
bool match = new[] {1,3}.ContainsSubsequence(new[] {1,2}); // match == true match = new[] {1,3}); // match == false
请注意,它假定目标序列没有空元素.
更新:感谢大家的赞成,但上面的代码实际上有一个错误!如果找到了部分匹配,但随后没有变成完全匹配,则该过程结束,而不是重置(当应用于{1,3}时,这显然是无法纠正的.ContainsSubsequence( {1,3})).
上面的代码非常适用于子序列的更常见定义(即不需要连续),但是为了处理重置(大多数IEnumerator不支持),需要预先枚举目标序列.这导致以下代码:
public static bool ContainsSubequence<T>(this IEnumerable<T> parent,IEnumerable<T> target) { bool foundOneMatch = false; var enumeratedTarget = target.ToList(); int enumPos = 0; using (IEnumerator<T> parentEnum = parent.GetEnumerator()) { while (parentEnum.MoveNext()) { if (enumeratedTarget[enumPos].Equals(parentEnum.Current)) { // Match,so move the target enum forward foundOneMatch = true; if (enumPos == enumeratedTarget.Count - 1) { // We went through the entire target,so we have a match return true; } enumPos++; } else if (foundOneMatch) { foundOneMatch = false; enumPos = 0; if (enumeratedTarget[enumPos].Equals(parentEnum.Current)) { foundOneMatch = true; enumPos++; } } } return false; } }