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

6 篇文章 0 订阅
6 篇文章 1 订阅

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

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值