加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 04:01:53 所属栏目:百科 来源:网络整理
导读:我需要找到其他大序列的序列,例如,{1,3,2,4,3}和{5,1,3中存在{1,3} }.有没有办法快速使用IEnumerable或其他东西? 解决方法 此方法将在父序列中找到可通过Equals()进行比较的任何类型的子序列: public static bool ContainsSubequenceT(this IEnumerableT p
我需要找到其他大序列的序列,例如,{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;
    }
}

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读