You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按顺序查找Array2的部分或全部元素在Array1中的首次出现索引

数组前缀匹配查找的最高效实现方案

你需要实现的是在长数组Array1中,查找与短数组Array2的前缀完全匹配的连续子数组的最早起始索引,你给出的示例中Array2的前3个元素["in", "the", "barn"]正好对应Array1索引9开始的3个元素,因此期望返回9。

最高效的实现方案为适配数组场景的KMP(Knuth-Morris-Pratt)匹配算法,该算法时间复杂度为O(n+m),其中n为Array1长度,m为Array2长度,避免了暴力匹配中重复回溯比对的性能损耗,在数组元素量级较大时优势尤其明显。

完整实现代码

using System;

public class ArrayPrefixMatch
{
    // 泛型方法,支持任意实现IEquatable<T>接口的元素类型数组匹配
    public static int FindFirstPrefixMatchIndex<T>(T[] textArray, T[] patternArray) where T : IEquatable<T>
    {
        // 边界校验
        if (textArray == null || patternArray == null || textArray.Length == 0 || patternArray.Length == 0)
            return -1;
        
        int textLen = textArray.Length;
        int patternLen = patternArray.Length;
        
        // 第一步:计算模式串的最长公共前后缀表(LPS数组,也叫部分匹配表)
        int[] lps = new int[patternLen];
        int maxPrefixLen = 0; // 当前最长公共前后缀的长度
        int index = 1;
        while (index < patternLen)
        {
            if (patternArray[index].Equals(patternArray[maxPrefixLen]))
            {
                maxPrefixLen++;
                lps[index] = maxPrefixLen;
                index++;
            }
            else
            {
                if (maxPrefixLen != 0)
                {
                    maxPrefixLen = lps[maxPrefixLen - 1];
                }
                else
                {
                    lps[index] = 0;
                    index++;
                }
            }
        }
        
        // 第二步:使用LPS数组执行KMP匹配,记录最长匹配对应的起始索引
        int textIndex = 0;
        int patternIndex = 0;
        int maxMatchLen = 0;
        int resultIndex = -1;
        
        while (textIndex < textLen)
        {
            if (patternArray[patternIndex].Equals(textArray[textIndex]))
            {
                textIndex++;
                patternIndex++;
                // 更新最长匹配记录
                if (patternIndex > maxMatchLen)
                {
                    maxMatchLen = patternIndex;
                    resultIndex = textIndex - patternIndex;
                    // 已完整匹配整个模式串,直接返回即可,不存在更长的匹配可能
                    if (maxMatchLen == patternLen)
                        return resultIndex;
                }
            }
            if (textIndex < textLen && !patternArray[patternIndex].Equals(textArray[textIndex]))
            {
                if (patternIndex != 0)
                    patternIndex = lps[patternIndex - 1];
                else
                    textIndex++;
            }
        }
        // 至少匹配1个元素才返回有效索引,否则返回-1
        return maxMatchLen >= 1 ? resultIndex : -1;
    }

    public static void Main()
    {
        string[] Array1 = { "the", "quick", "brown", "fox", "jumps",
                            "over", "the", "lazy", "dog", "in", "the",
                            "barn" };

        string[] Array2 = { "in", "the", "barn", "next", "to",
                            "the", "chickens" };
        
        int index = FindFirstPrefixMatchIndex(Array1, Array2);
        Console.WriteLine("The first occurrence of partial Array2 is at index {0}.", index);
        // 输出结果为9,符合预期
    }
}

小数组场景的简化实现

如果你处理的数组长度都非常小(单个数组元素数低于100),也可以用暴力匹配实现,代码更简洁,但最坏时间复杂度为O(n*m),不适合大数组场景:

public static int BruteForcePrefixMatch<T>(T[] textArray, T[] patternArray) where T : IEquatable<T>
{
    if (textArray == null || patternArray == null || textArray.Length == 0 || patternArray.Length == 0)
        return -1;
    
    int maxMatchLen = 0;
    int resultIndex = -1;
    for (int i = 0; i < textArray.Length; i++)
    {
        int currentMatch = 0;
        for (int j = 0; j < patternArray.Length && i + j < textArray.Length; j++)
        {
            if (textArray[i + j].Equals(patternArray[j]))
                currentMatch++;
            else
                break;
        }
        if (currentMatch > maxMatchLen)
        {
            maxMatchLen = currentMatch;
            resultIndex = i;
            if (maxMatchLen == patternArray.Length)
                return resultIndex;
        }
    }
    return maxMatchLen > 0 ? resultIndex : -1;
}

内容的提问来源于stack exchange,提问作者99Boboster99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:24:00