我有一张关键字表:tblKeywords(字段 fldKeyword <varchar>),一共有100-200万条记录。
同时我每天要处理10000封email,要对每一封email做关键字匹配,凡是email的Body中存在tblKeywords表中任意一条fldKeyword记录的字符串值,就算匹配成功,否则不成功。我要做个程序实现上面功能。
我想到的算法是:
1.把关键字表tblKeywords所有记录读到内存变量datatable中
2.对每一封email,遍历内存变量datatable,对当前fldKeyword的字符串值,搜索email的Body,如果有此Keyword,成功,跳出;如果没有此Keyword,继续匹配下一个fldKeyword记录,直到匹配到或匹配完退出。但是这个算法貌似很费时间,2个循环嵌套,最大可能须比较100-200万 * 10000 = 100亿次。请教高手有没有更快速的算法?
谢谢!
在线等!
同时我每天要处理10000封email,要对每一封email做关键字匹配,凡是email的Body中存在tblKeywords表中任意一条fldKeyword记录的字符串值,就算匹配成功,否则不成功。我要做个程序实现上面功能。
我想到的算法是:
1.把关键字表tblKeywords所有记录读到内存变量datatable中
2.对每一封email,遍历内存变量datatable,对当前fldKeyword的字符串值,搜索email的Body,如果有此Keyword,成功,跳出;如果没有此Keyword,继续匹配下一个fldKeyword记录,直到匹配到或匹配完退出。但是这个算法貌似很费时间,2个循环嵌套,最大可能须比较100-200万 * 10000 = 100亿次。请教高手有没有更快速的算法?
谢谢!
在线等!
解决方案 »
- Vs2005 C# 给窗体绘制边框
- 分不高是因为散了,有个自建线程池的问题,上网查了还是没有解决,有心人过来看看
- C#编写,把excel 中的数据导入Sql server
- 如何判断某应用程序是否在运行
- 内存溢出(350万数据检测正常,200万数据却出现内存溢出),请仁兄帮忙
- 求一段获取本机端口数据代码
- ====简单问题:WinForm里面:如何将用户控件内Panel的事件映射到UserControl的事件?====
- c#+wmi 管理DNS服务器
- javascript中比较一个字符串是否包括一个字符串的方法是什么?
- C#中子窗口手动关闭之后,老是报句柄错误
- Form 程序中的 两个 App.Config
- 一共三个整型变量a,b,c,用最简单的方法获取值最大的那个变量,注: 不是最大值是变量
我前几天自己测试了一下。一个while循环1秒钟做简单的3次判断, 可以循环300多万次吧,如果对于一100亿级别的数据100/0.03 = 30000秒,所以在我个人电脑上做简单的运算也要8,9个小时。。 所以我向服务器也快不到那里去把
class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
string[] keywords = { "房价畸形", "房奴谁之过?", "生活质量" };
string text = "沦为房奴谁之过?为房憔悴伤神是何原因"; Trie trie = new Trie();
foreach (string keyword in keywords) trie.Add(keyword); string foundKeyword = null;
for (int i = 0; i < text.Length && foundKeyword == null; i++)
{
object token = null;
for (int j = i; j < text.Length; j++)
{
if (trie.Exist(text[j], ref token))
{
foundKeyword = text.Substring(i, j - i + 1);
MessageBox.Show(foundKeyword);
break;
}
if (token == null) break;
}
}
}
}public class Trie
{
TrieNode root = new TrieNode((char)0);
public void Add(string word)
{
TrieNode node = root;
foreach (char c in word)
{
node = node.AddChild(c);
}
node.AddChild((char)0);
}
public bool Exist(string word)
{
TrieNode node = root;
foreach (char c in word)
{
node = node.GetChild(c);
if (node == null) return false;
}
return node.GetChild((char)0) != null;
}
public bool Exist(char c, ref object token)
{
TrieNode node = (token as TrieNode ?? this.root).GetChild(c);
token = node;
return node !=null && node.Terminated;
}
class TrieNode
{
private char value;
private SortedList<char, TrieNode> childNodes = new SortedList<char, TrieNode>(); public TrieNode(char c)
{
this.value = c;
}
public TrieNode GetChild(char c)
{
TrieNode node = null;
childNodes.TryGetValue(c, out node);
return node;
}
public TrieNode AddChild(char c)
{
TrieNode node = GetChild(c);
if (node == null)
{
this.childNodes.Add(c, node = new TrieNode(c));
}
return node;
}
public bool Terminated { get { return this.childNodes.ContainsKey((char)0); } }
}
}
email是不好断字的。谢谢,gomoku的高手算法!关于前缀树,我还有一个问题,如果我想把email中的所有匹配的关键词都找出来,而不是找到一个就终止,请教您上面的代码该如何修改啊?谢谢!!