加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 在列表中搜索数组或列表

发布时间:2020-12-15 08:34:26 所属栏目:百科 来源:网络整理
导读:有 Listbyte lbyte 有 byte[] searchBytes 如何搜索lbyte不仅仅是一个字节,而是搜索searchBytes的索引? 例如. Int32 index = lbyte.FirstIndexOf(searchBytes); 这是我提出的蛮力. 不是我要找的表现. public static Int32 ListIndexOfArray(Listbyte lb,byt
List<byte> lbyte

byte[] searchBytes

如何搜索lbyte不仅仅是一个字节,而是搜索searchBytes的索引?
例如.

Int32 index = lbyte.FirstIndexOf(searchBytes);

这是我提出的蛮力.
不是我要找的表现.

public static Int32 ListIndexOfArray(List<byte> lb,byte[] sbs)
{
    if (sbs == null) return -1;
    if (sbs.Length == 0) return -1;
    if (sbs.Length > 8) return -1;
    if (sbs.Length == 1) return lb.FirstOrDefault(x => x == sbs[0]);
    Int32 sbsLen = sbs.Length;
    Int32 sbsCurMatch = 0;
    for (int i = 0; i < lb.Count; i++)
    {
        if (lb[i] == sbs[sbsCurMatch])
        {
            sbsCurMatch++;
            if (sbsCurMatch == sbsLen)
            {
                //int index = lb.FindIndex(e => sbs.All(f => f.Equals(e)));  // fails to find a match
                IndexOfArray = i - sbsLen + 1;
                return;
            }
        }
        else 
        {
            sbsCurMatch = 0;
        }
    }
    return -1;
}

解决方法

你可能会发现 Boyer-Moore algorithm在这里很有用.将列表转换为数组并进行搜索.算法代码取自 this post.
static int SimpleBoyerMooreSearch(byte[] haystack,byte[] needle)
{
    int[] lookup = new int[256];
    for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Length; }

    for (int i = 0; i < needle.Length; i++)
    {
        lookup[needle[i]] = needle.Length - i - 1;
    }

    int index = needle.Length - 1;
    var lastByte = needle.Last();
    while (index < haystack.Length)
    {
        var checkByte = haystack[index];
        if (haystack[index] == lastByte)
        {
            bool found = true;
            for (int j = needle.Length - 2; j >= 0; j--)
            {
                if (haystack[index - needle.Length + j + 1] != needle[j])
                {
                    found = false;
                    break;
                }
            }

            if (found)
                return index - needle.Length + 1;
            else
                index++;
        }
        else
        {
            index += lookup[checkByte];
        }
    }
    return -1;
}

然后你可以这样搜索.如果lbyte在一段时间后保持不变,你可以将它转换为一个数组并传递它.

//index is returned,or -1 if 'searchBytes' is not found
int startIndex = SimpleBoyerMooreSearch(lbyte.ToArray(),searchBytes);

根据评论更新.这是IList实现,这意味着可以传递数组和列表(以及实现IList的任何其他内容)

static int SimpleBoyerMooreSearch(IList<byte> haystack,IList<byte> needle)
 {
    int[] lookup = new int[256];
    for (int i = 0; i < lookup.Length; i++) { lookup[i] = needle.Count; }

    for (int i = 0; i < needle.Count; i++)
    {
        lookup[needle[i]] = needle.Count - i - 1;
    }

    int index = needle.Count - 1;
    var lastByte = needle[index];
    while (index < haystack.Count)
    {
        var checkByte = haystack[index];
        if (haystack[index] == lastByte)
        {
            bool found = true;
            for (int j = needle.Count - 2; j >= 0; j--)
            {
                if (haystack[index - needle.Count + j + 1] != needle[j])
                {
                    found = false;
                    break;
                }
            }

            if (found)
                return index - needle.Count + 1;
            else
                index++;
        }
        else
        {
            index += lookup[checkByte];
        }
    }
    return -1;
}

由于数组和列表实现了IList,因此在您的情况下调用它时不需要进行转换.

int startIndex = SimpleBoyerMooreSearch(lbyte,searchBytes);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读