【.NET / C#】SubarrayUtils(查找子数组工具类)

C# 查找子数组工具类

/// <summary>/// Code shared to do searches/// </summary>public class SubarrayUtils{    /// <summary>    /// Code shared by ArraySegment to do searches.    /// The source is the ArraySegment being searched, and the target is the ArraySegment being searched for.     /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the ArraySegment being searched</param>    /// <param name="target">the ArraySegment being searched for</param>    /// <returns></returns>    public static int IndexOf<T>(ArraySegment<T> source, ArraySegment<T> target) where T : struct    {        return IndexOf(source.Array, source.Offset, source.Count, target.Array, target.Offset, target.Count);    }    /// <summary>    /// Code shared by array to do searches.    /// The source is the array being searched, and the target is the array being searched for.    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the array being searched</param>    /// <param name="sourceOffset">offset of the source array</param>    /// <param name="sourceCount">count of the source array</param>    /// <param name="target">the array being searched for</param>    /// <param name="targetOffset">offset of the target array</param>    /// <param name="targetCount">count of the target array</param>    /// <returns></returns>    public static int IndexOf<T>(        T[] source, int sourceOffset, int sourceCount,        T[] target, int targetOffset, int targetCount) where T : struct    {        return IndexOf(source, sourceOffset, sourceCount, target, targetOffset, targetCount, 0);    }    /// <summary>    /// Code shared by array to do searches.    /// The source is the array being searched, and the target is the array being searched for.    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the array being searched</param>    /// <param name="sourceOffset">offset of the source array</param>    /// <param name="sourceCount">count of the source array</param>    /// <param name="target">the array being searched for</param>    /// <param name="targetOffset">offset of the target array</param>    /// <param name="targetCount">count of the target array</param>    /// <param name="fromIndex">the index to begin searching from</param>    /// <returns></returns>    internal static int IndexOf<T>(        T[] source, int sourceOffset, int sourceCount,        T[] target, int targetOffset, int targetCount, int fromIndex) where T : struct    {        if (fromIndex >= sourceCount)        {            return (targetCount == 0 ? sourceCount : -1);        }        if (fromIndex < 0)        {            fromIndex = 0;        }        if (targetCount == 0)        {            return fromIndex;        }        T first = target[targetOffset];        int max = sourceOffset + (sourceCount - targetCount);        for (int i = sourceOffset + fromIndex; i <= max; i++)        {            if (!Equals(source[i], first))            {                while (++i <= max && !Equals(source[i], first)) ;            }            if (i <= max)            {                int j = i + 1;                int end = j + targetCount - 1;                for (int k = targetOffset + 1; j < end && Equals(source[j], target[k]); j++, k++) ;                if (j == end)                {                    return i - sourceOffset;                }            }        }        return -1;    }    /// <summary>    /// Code shared by ArraySegment to do searches.    /// The source is the ArraySegment being searched, and the target is the ArraySegment being searched for.    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the ArraySegment being searched</param>    /// <param name="target">the ArraySegment being searched for</param>    /// <returns></returns>    public static int LastIndexOf<T>(ArraySegment<T> source, ArraySegment<T> target) where T : struct    {        return LastIndexOf(source.Array, source.Offset, source.Count, target.Array, target.Offset, target.Count);    }    /// <summary>    /// Code shared by array to do searches.    /// The source is the array being searched, and the target is the array being searched for.    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the array being searched</param>    /// <param name="sourceOffset">offset of the source array</param>    /// <param name="sourceCount">count of the source array</param>    /// <param name="target">the array being searched for</param>    /// <param name="targetOffset">offset of the target array</param>    /// <param name="targetCount">count of the target array</param>    /// <returns></returns>    public static int LastIndexOf<T>(        T[] source, int sourceOffset, int sourceCount,        T[] target, int targetOffset, int targetCount) where T : struct    {        return LastIndexOf(source, sourceOffset, sourceCount, target, targetOffset, targetCount, sourceOffset + sourceCount);    }    /// <summary>    /// Code shared by array to do searches.    /// The source is the array being searched, and the target is the array being searched for.    /// </summary>    /// <typeparam name="T"></typeparam>    /// <param name="source">the array being searched</param>    /// <param name="sourceOffset">offset of the source array</param>    /// <param name="sourceCount">count of the source array</param>    /// <param name="target">the array being searched for</param>    /// <param name="targetOffset">offset of the target array</param>    /// <param name="targetCount">count of the target array</param>    /// <param name="fromIndex">the index to begin searching from</param>    /// <returns></returns>    internal static int LastIndexOf<T>(        T[] source, int sourceOffset, int sourceCount,        T[] target, int targetOffset, int targetCount, int fromIndex) where T : struct    {        int rightIndex = sourceCount - targetCount;        if (fromIndex < 0)        {            return -1;        }        if (fromIndex > rightIndex)        {            fromIndex = rightIndex;        }        if (targetCount == 0)        {            return fromIndex;        }        int arrLastIndex = targetOffset + targetCount - 1;        T arrLastItem = target[arrLastIndex];        int min = sourceOffset + targetCount - 1;        int i = min + fromIndex;        startSearchForLastItem:        while (true)        {            while (i >= min &&  !Equals(source[i], arrLastItem))            {                i--;            }            if (i < min)            {                return -1;            }            int j = i - 1;            int start = j - (targetCount - 1);            int k = arrLastIndex - 1;            while (j > start)            {                if (!Equals(source[j--], target[k--]))                {                    i--;                    goto startSearchForLastItem;                }            }            return start - sourceOffset + 1;        }    }}
(0)

相关推荐