C# · 12月 26, 2021

c# – 以更长的顺序查找子序列

我需要找到其他大序列的序列,例如,{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 == truematch = 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; }}

此代码没有任何错误,但不适用于大型(或无限)序列.