C# 在列表中查找相同的模式

C# 在列表中查找相同的模式,c#,list,pattern-matching,C#,List,Pattern Matching,假设我们有以下列表: List<int> Journey1 = new List<int>() { 1, 2, 3, 4, 5 }; List<int> Journey2 = new List<int>() { 2, 3, 4, 6, 7, 3, 4 }; List<int> Journey3 = new List<int>() { 6, 7, 1 }; List<int> Jou

假设我们有以下列表:

    List<int> Journey1 = new List<int>() { 1, 2, 3, 4, 5 };
    List<int> Journey2 = new List<int>() { 2, 3, 4, 6, 7, 3, 4 };
    List<int> Journey3 = new List<int>() { 6, 7, 1 };
    List<int> Journey4 = new List<int>() { 3, 1, 4 };
我们有5000个列表,每个列表大约有200个项目,因此模式可以有1-200个项目,可以在1-5000个列表中看到


因此,我需要一种非常快速的模式匹配方法。

无需预计算,只需简单的即时搜索:

var matchedJourneys = journeys.Where(x => ContainsPattern(x, mypattern));

bool ContainsPattern(List<int> list, List<int> pattern)
{
    for(int i = 0; i < list.Count - (pattern.Count - 1); i++)
    {
        var match = true;
        for(int j = 0; j < pattern.Count; j++)  
            if(list[i + j] != pattern[j])
                     {
                         match = false;
                         break;
                     }
        if(match) return true;
    }
    return false;
}
var matchedJourneys=journeys.Where(x=>ContainsPattern(x,mypattern));
bool ContainsPattern(列表、列表模式)
{
对于(int i=0;i
这将对您的“数字”执行最多2亿次相等检查。但是,由于不希望对整个模式执行检查,如果检查所有列表,这可能(只是一个猜测)~500万个相等操作。那是几百毫秒


这完全取决于什么对你来说“非常快”。如果这太慢,你将需要一个更复杂的方法

无需预计算和简单的即时搜索:

var matchedJourneys = journeys.Where(x => ContainsPattern(x, mypattern));

bool ContainsPattern(List<int> list, List<int> pattern)
{
    for(int i = 0; i < list.Count - (pattern.Count - 1); i++)
    {
        var match = true;
        for(int j = 0; j < pattern.Count; j++)  
            if(list[i + j] != pattern[j])
                     {
                         match = false;
                         break;
                     }
        if(match) return true;
    }
    return false;
}
var matchedJourneys=journeys.Where(x=>ContainsPattern(x,mypattern));
bool ContainsPattern(列表、列表模式)
{
对于(int i=0;i
这将对您的“数字”执行最多2亿次相等检查。但是,由于不希望对整个模式执行检查,如果检查所有列表,这可能(只是一个猜测)~500万个相等操作。那是几百毫秒


这完全取决于什么对你来说“非常快”。如果这太慢,你将需要一个更复杂的方法

我不确定您想要什么作为输出。我只是试了一下

我建议您创建一个列表,而不是声明单个列表变量

List<List<int>> journeys = new List<List<int>>();
journeys.Add(new List<int>() { 1, 2, 3, 4, 5 });
journeys.Add(new List<int>() { 2, 3, 4, 6, 7, 3, 4 });
journeys.Add(new List<int>() { 6, 7, 1 });
journeys.Add(new List<int>() { 3, 1, 4 });
这个测试回路

foreach (var item in result) {
    Console.Write("Number {0} occurs in list # ", item.number);
    foreach (var index in item.listIndexes) {
        Console.Write("{0} ", index);
    }
    Console.WriteLine();
}
你会得到这个结果

Number 1 occurs in list # 0 2 3 Number 2 occurs in list # 0 1 Number 3 occurs in list # 0 1 3 Number 4 occurs in list # 0 1 3 Number 5 occurs in list # 0 Number 6 occurs in list # 1 2 Number 7 occurs in list # 1 2 数字1出现在列表#0 2 3中 数字2出现在列表#0 1中 数字3出现在列表#0 1 3中 数字4出现在列表#0 1 3中 数字5出现在列表#0中 数字6出现在列表#1 2中 数字7出现在列表#1 2中
列表从零开始编号。

我不确定您想要什么作为输出。我只是试了一下

我建议您创建一个列表,而不是声明单个列表变量

List<List<int>> journeys = new List<List<int>>();
journeys.Add(new List<int>() { 1, 2, 3, 4, 5 });
journeys.Add(new List<int>() { 2, 3, 4, 6, 7, 3, 4 });
journeys.Add(new List<int>() { 6, 7, 1 });
journeys.Add(new List<int>() { 3, 1, 4 });
这个测试回路

foreach (var item in result) {
    Console.Write("Number {0} occurs in list # ", item.number);
    foreach (var index in item.listIndexes) {
        Console.Write("{0} ", index);
    }
    Console.WriteLine();
}
你会得到这个结果

Number 1 occurs in list # 0 2 3 Number 2 occurs in list # 0 1 Number 3 occurs in list # 0 1 3 Number 4 occurs in list # 0 1 3 Number 5 occurs in list # 0 Number 6 occurs in list # 1 2 Number 7 occurs in list # 1 2 数字1出现在列表#0 2 3中 数字2出现在列表#0 1中 数字3出现在列表#0 1 3中 数字4出现在列表#0 1 3中 数字5出现在列表#0中 数字6出现在列表#1 2中 数字7出现在列表#1 2中
列表从零开始编号。

对于暴力方法,您可以尝试使用它来加速子节匹配。仍然需要大量的比较,但不管子序列长度如何,至少匹配可以几乎保持不变。

对于暴力方法,您可以尝试使用它来加速子部分匹配。仍然需要大量的比较,但不管子序列长度如何,至少匹配可以几乎保持不变。

在您的情况下,有机会从模式预处理和文本预处理中获益(http://en.wikipedia.org/wiki/String_searching_algorithm)


例如,为列表中的所有子序列构造一个trie将允许查询该列表中与模式长度成比例的给定模式。

在您的情况下,有机会从模式预处理和文本预处理中获益(http://en.wikipedia.org/wiki/String_searching_algorithm)


例如,为列表中的所有子序列构造一个trie将允许查询该列表中与模式长度成比例的给定模式。

您能解释一下规则吗?例如,为什么不是
3->Journey1,Journey2,Journey4
噢,模式是(序列)=>(要搜索的列表)?我们需要从最长到最短找到模式,因此首先我选择了2,3,4,这是在多个旅程中看到的最长模式。你能解释一下规则吗?例如,为什么不是
3->Journey1,Journey2,Journey4
噢,模式是(序列)=>(要搜索的列表)?我们需要从最长到最短找到模式,因此首先我选择了2,3,4,这是在多个旅程中看到的最长模式。这是n^2,它不会创建要查找的模式。只是将模式与列表匹配。这只是工作的一半。目前还不清楚这些模式是已知的还是尚未发现。我假设它们是已知的,因为问题给了我们“单一”项模式,比如“1”和“5”(用机器学习发现这样的模式是没有意义的)。非常感谢Darjan,但正如jb所说,它不会创建模式,它应该开始创建模式,要创建模式,我们有一个简单的角色,每个模式至少应该在一次旅程中看到。在进程结束时,如果某些节点仍保留在列表中,而这些列表不在任何模式中,我们会将它们添加为新模式。这是n^2,它不会创建要查找的模式。只是将模式与列表匹配。这只是工作的一半。目前还不清楚这些模式是已知的还是尚未发现。我假设它们是已知的,因为问题给了我们“单一”项模式,比如“1”和“5”(用机器学习发现这样的模式是没有意义的)。非常感谢Darjan,但正如jb所说,它不创建模式,它应该开始创建模式,创建模式