如何确定一个数组是另一个数组的一部分?

时间:2011-01-11 13:52:09

标签: c# .net arrays

例如:我有数组

var src = new byte[] {1, 2, 3, 4, 5};
var tag = new byte[] {3, 4};

谁知道快速找到标签数组索引的方法? 我需要以下内容:

int FindIndexOfSeq(byte[] src, byte[] sequence);

序列在src中可以多次出现。

解决方案:How to find index of sublist in list?

5 个答案:

答案 0 :(得分:2)

这是获取索引的一种方法

for (int i = 0; i < (src.Length - tag.Length); i++ )
{
    if (tag.SequenceEqual(src.Skip(i).Take(tag.Length)))
        Console.WriteLine("It's at position " + i);
}

不幸的是,它很慢。

如果您只是想知道tag中是否可以src找到所有项目(按任意顺序),那么

var src = new byte[] { 1, 2, 3, 4, 5 }; 
var tag = new byte[] { 4, 3 };

if (src.Intersect(tag).Count() == tag.Length)
    Console.WriteLine("tag can be found in src!");

答案 1 :(得分:2)

你能得到的最好的是O(m),但是我的实现稍微复杂一些。如果您满足O(m * n)作为最坏情况的解决方案,您可以使用下面的解决方案。如果您的序列是有序的,并且tag数组中的起始项仅在src中出现一次,这也将导致O(m)。

class Program
{
    static void Main(string[] args)
    {
        var src = new byte[] { 1, 2, 3, 4, 5 };
        var tag = new byte[] { 3, 4 };
        var index = FindIndexOfSeq(src, tag);
        Console.WriteLine(index);
        Console.ReadLine();
    }
    static int FindIndexOfSeq<T>(T[] src, T[] seq)
    {
        int index = -1;
        for (int i = 0; i < src.Length - seq.Length + 1; i++)
        {
            bool foundSeq = true;
            for (int j = 0; j < seq.Length; j++)
            {
                foundSeq = foundSeq && src[i + j].Equals(seq[j]);
            }
            if (foundSeq)
            {
                index = i;
                break;
            }
        }
        return index;
    }
}

我假设序列必须按顺序排列,我只在firefox中编译它,所以不确定它是否有效:)。此外,我使它通用,因此它处理任何类型的数组,而不仅仅是字节。

更新:更新的代码编译并正常工作...或者我的简单测试有效。

答案 2 :(得分:1)

int FindIndexOfSeq<T>(byte[] src, byte[] tag)
{
    Int32 tagCount = tag.Count();            

    // If `tag` is not empty and `src` contains `tag`
    if (tagCount > 0 && src.Intersect(tag).Count() == tagCount)
    {
        // Find index of first element in `tag`
        Int32 tagStartIndex = Array.IndexOf(src, tag.First());

        // Get the matching slice of `tag` from `src`
        var newSrc = src.Skip(tagStartIndex).Take(tag.Count()).ToList();

        // Zip them together using their difference
        var sum = Enumerable.Zip(tag, newSrc, (i1, i2) => Convert.ToInt32(i2 - i1)).Sum();

        // If total of their differences is zero, both sequences match
        if (sum == 0)
        {
            // return starting index of `tag` in `src`
            return tagStartIndex;
        }
    }

    // return `Not Found`
    return -1;
}

答案 3 :(得分:1)

此任务等于在字符串中搜索子字符串。为此,您可以使用任何KMP算法以获得更好的性能: http://exclusiveminds.com/2009/12/09/kmp-string-searching-algorithm-in-c/

答案 4 :(得分:0)