检查数组是否包含与其他数组完全相同的序列

本文关键字:数组 是否 包含 其他 检查 | 更新日期: 2023-09-27 18:15:02

我有一个问题,我需要检查一些数组是否是更大数组的一部分,这将是相当容易的,但我需要检查更大的数组是否包含完全相同的序列。例如

int[] greaterArray = {8, 3, 4, 5, 9, 12, 6 ... n - elements}
int[] lesserArray = {3, 4, 5}

现在我需要知道如果较小的数组是这个数组的一部分,但具有相同的序列,所以它包含3,4,5相邻的较大数组。

我试着:

var exists = greaterArray.Intersect(lesserArray).Any();

但是如果较小数组的任何元素存在于较大数组中,则返回信息,而不是精确的序列。什么好主意吗?

检查数组是否包含与其他数组完全相同的序列

    int[] greaterArray = {8, 3, 4, 5, 9, 12, 6};
    int[] lesserArray = { 3, 4, 5 };
    bool sequenceFound = false;
    for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
    {
        if (greaterArray.Skip(i).Take(lesserArray.Length).SequenceEqual(lesserArray))
        {
            sequenceFound = true;
            break;
        }
    }
    if (sequenceFound)
    {
        //sequence found
    }
    else
    {
        //sequence not found
    }

使用上面的代码。它从greaterArray中取多个长度等于lesserArray长度的子序列,并将其与lesserArray进行匹配。

更通用一点,不使用LINQ:

int[] greaterArray = {8, 2, 4, 5, 9, 12, 3, 4, 5};
int[] lesserArray = {3, 4, 5};
for (int i = 0; i <= greaterArray.Length - lesserArray.Length; i++)
            {
                var sub = greaterArray.SubArray(i, lesserArray.Length);
                if (Enumerable.SequenceEqual(sub, lesserArray))
                {
                    Console.WriteLine("Equals!");
                }
            }

这个用来得到SubArray:

public static T[] SubArray<T>(this T[] data, int index, int length)
        {
            T[] result = new T[length];
            Array.Copy(data, index, result, 0, length);
            return result;
        }

这应该可以完成你的工作

int[] grtarr = { 8, 3, 4, 5, 9, 12, 6 };
int[] lsarr = { 3, 4, 5 };
List<int> lstGrtArr = grtarr.ToList();
List<int> lstLsrArr = lsarr.ToList();
bool sequenceMatch = false;
for (int i = 0; i < grtarr.Count(); i++)
{
    if (lstGrtArr.Where(x => lstGrtArr.IndexOf(x) >= i).Take(lstLsrArr.Count()).SequenceEqual(lstLsrArr))
    {
        sequenceMatch = true;
        break;
    }
}
if(sequenceMatch)
{
    //Do Something
}
    static bool isPrefix(int[] source, int start_pos, int[] prefix)
    {
        bool result = start_pos + prefix.Length <= source.Length;
        for (int i = 0; result && i < prefix.Length; ++i, ++start_pos)
            result = source[start_pos] == prefix[i];
        return result;
    }
    static bool Contains(int[] source, int[] prefix)
    {
        bool result = false;
        for (int i = 0; !result && i < source.Length; ++i)
            result = source[i] == prefix[0] ? isPrefix(source, i, prefix) : false;
        return result;
    }

使用这段代码:

public bool ArraysEqual<T>(T[] a1, T[] a2)
{
    if (ReferenceEquals(a1,a2))
        return true;
    if (a1 == null || a2 == null)
        return false;
    if (a1.Length != a2.Length)
        return false;
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < a1.Length; i++)
    {
        if (!comparer.Equals(a1[i], a2[i])) return false;
    }
    return true;
}

或者如果你想使用Linq而不太关心性能,最简单的方法是:

var arrays_are_the_same = Enumerable.SequenceEqual(a1, a2);