如何在另一个列表中找到列表的位置



我正在使用两个列表。第一个包含大量的字符串。第二个包含较小的字符串列表。我需要找到第二个列表中的第二个列表中存在的位置。

我使用枚举工作,由于数据的尺寸很大,这很慢,我希望能更快。

    List<string> first = new List<string>() { "AAA","BBB","CCC","DDD","EEE","FFF" };
    List<string> second = new List<string>() { "CCC","DDD","EEE" };
int x = SomeMagic(first,second);

我需要x = 2。

好吧,这是我的变体,与旧的each-loop:

private int SomeMagic(IEnumerable<string> source, IEnumerable<string> target)
{
    /* Some obvious checks for `source` and `target` lenght / nullity are ommited */
    // searched pattern
    var pattern = target.ToArray();
    // candidates in form `candidate index` -> `checked length`
    var candidates = new Dictionary<int, int>();
    // iteration index
    var index = 0;
    // so, lets the magic begin
    foreach (var value in source)
    {
        // check candidates
        foreach (var candidate in candidates.Keys.ToArray()) // <- we are going to change this collection
        {
            var checkedLength = candidates[candidate];
            if (value == pattern[checkedLength]) // <- here `checkedLength` is used in sense `nextPositionToCheck`
            {
                // candidate has match next value
                checkedLength += 1;
                // check if we are done here
                if (checkedLength == pattern.Length) return candidate; // <- exit point
                candidates[candidate] = checkedLength;
            }
            else
                // candidate has failed
                candidates.Remove(candidate);
        }
        // check for new candidate
        if (value == pattern[0])
            candidates.Add(index, 1);
        index++;
    }
    // we did everything we could
    return -1;
}

我们使用候选人字典来处理以下情况:

var first = new List<string> { "AAA","BBB","CCC","CCC","CCC","CCC","EEE","FFF" };
var second = new List<string> { "CCC","CCC","CCC","EEE" };

如果您愿意使用Morelinq,请考虑使用Window

var windows = first.Window(second.Count);
var result = windows
                .Select((subset, index) => new { subset, index = (int?)index })
                .Where(z => Enumerable.SequenceEqual(second, z.subset))
                .Select(z => z.index)
                .FirstOrDefault();
Console.WriteLine(result);
Console.ReadLine();

Window将允许您查看块中数据的"切片"(基于second列表的长度(。那么SequenceEqual可以用于查看切片是否等于second。如果是,则可以返回index。如果找不到匹配项,null将被返回。

实现的体积方法如下,如果找不到匹配,则将返回-1,否则将返回第一个列表中的启动元素的索引。

private int SomeMagic(List<string> first, List<string> second)
{
    if (first.Count < second.Count)
    {
        return -1;
    }
    for (int i = 0; i <= first.Count - second.Count; i++)
    {
        List<string> partialFirst = first.GetRange(i, second.Count);
        if (Enumerable.SequenceEqual(partialFirst, second))
            return i;
    }
    return -1;
}

您可以使用namepace System.Linq

使用Intersect扩展方法
var CommonList = Listfirst.Intersect(Listsecond)

相关内容

  • 没有找到相关文章

最新更新