我需要找到其他大序列的序列,例如,{1,3,2,4,3}和{5,1,3中存在{1,3} }.有没有办法快速使用IEnumerable或其他东西?
解决方法
此方法将在父序列中找到可通过Equals()进行比较的任何类型的子序列:
@H_403_6@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;
}
}
}
你可以像这样使用它:
@H_403_6@bool match = new[] {1,3}.ContainsSubsequence(new[] {1,2}); // match == true match = new[] {1,3}); // match == false请注意,它假定目标序列没有空元素.
更新:感谢大家的赞成,但上面的代码实际上有一个错误!如果找到了部分匹配,但随后没有变成完全匹配,则该过程结束,而不是重置(当应用于{1,3}时,这显然是无法纠正的.ContainsSubsequence( {1,3})).
上面的代码非常适用于子序列的更常见定义(即不需要连续),但是为了处理重置(大多数IEnumerator不支持),需要预先枚举目标序列.这导致以下代码:
@H_403_6@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; } }