优化简单的搜索算法

我一直在玩一个相当简单的自制搜索引擎,现在我正在考虑一些相关性排序代码。

它不是很漂亮,但是当谈到聪明的算法时我不是很好,所以我希望我能得到一些建议:)

基本上,我希望每个搜索结果都根据与搜索条件匹配的单词数得分。 每个确切单词3分,部分匹配1分

例如,如果我搜索“冬天的雪”,这些将是结果:

  • 冬天的 => 6点
  • 冬天 下雪 => 4分
  • 冬季 降雪 => 4分
  • 冬日阳光=> 3分
  • 冬季 降雪 => 2分

这是代码:

String[] resultWords = result.split(" "); String[] searchWords = searchStr.split(" "); int score = 0; for (String resultWord : resultWords) { for (String searchWord : searchWords) { if (resultWord.equalsIgnoreCase(searchWord)) score += 3; else if (resultWord.toLowerCase().contains(searchWord.toLowerCase())) score++; } } 

你的代码对我来说似乎没问题。 我建议一点变化:

由于您正在经历所有可能的组合,因此您可能会在开始时获得背面的toLowerCase()

此外,如果已经发生完全匹配,则不需要执行另一个equals

  result = result.toLowerCase(); searchStr = searchStr.toLowerCase(); String[] resultWords = result.split(" "); String[] searchWords = searchStr.split(" "); int score = 0; for (String resultWord : resultWords) { boolean exactMatch = false; for (String searchWord : searchWords) { if (!exactMatch && resultWord.equals(searchWord)) { exactMatch = true; score += 3; } else if (resultWord.contains(searchWord)) score++; } } 

当然,这是一个非常基本的水平。 如果您真的对计算机科学领域感兴趣并希望了解有关实现搜索引擎的更多信息,请从以下术语开始:

  • 自然语言处理
  • 信息检索
  • 文本挖掘
  • 词干
  • 对于首字母缩略词,区分大小写非常重要,即SUN ; 任何与内容和案例相匹配的单词必须加权超过3分(5或7)?
  • 使用策略设计模式

例如,考虑这个天真的分数模型:

 interface ScoreModel { int startingScore(); int partialMatch(); int exactMatch(); } 

 int search(String result, String searchStr, ScoreModel model) { String[] resultWords = result.split(" "); String[] searchWords = searchStr.split(" "); int score = model.startingScore(); for (String resultWord : resultWords) { for (String searchWord : searchWords) { if (resultWord.equalsIgnoreCase(searchWord)) { score += model.exactMatch(); } else if (resultWord.toLowerCase().contains(searchWord.toLowerCase())) { score += model.partialMatch(); } } } return score; } 

可以通过预处理数据库来完成基本优化:不要每次都将条目拆分为单词。

在将数据添加到数据库期间为每个条目构建单词列表(首选哈希或二进制树以加速列表中的搜索),删除所有太短的单词,小写并存储此数据以供进一步使用。

在搜索开始时使用搜索字符串执行相同的操作(拆分,小写,清理),并使用此单词列表与每个输入单词列表进行比较。

1)您可以先对searchWords进行排序。 一旦结果词按字母顺序排列在当前搜索词之后,您就可以跳出循环。

2)更好的是,对两者进行排序,然后同时沿着两个列表一起查找发生匹配的位置。

您可以使用正则表达式来查找匹配模式的模式和长度(用于后面的分类/评分)。