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 == 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;
    }
}

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

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...