【发布时间】:2014-04-02 23:10:18
【问题描述】:
我正在寻找在许多短文本行(干草堆)中找到非常短的子字符串(模式、针)。但是,我不太确定在幼稚的蛮力方法之外使用哪种方法。
背景:我正在做一个有趣的附带项目,我收到多个用户的短信聊天日志(2000-15000 行文本和 2-50 个用户),我想找到所有各种模式匹配在基于我想出的预定词的聊天记录中。到目前为止,我正在寻找大约 1600 种模式,但我可能会寻找更多。
例如,我想找出在平均短信日志中使用的与食物相关的词的数量,例如“汉堡包”、“披萨”、“可乐”、“午餐”、“晚餐”、“餐厅” ”、“麦当劳”。虽然我给出了英语示例,但我实际上会在我的程序中使用韩语。这些指定的单词中的每一个都有自己的分数,我将其分别作为键和值放入哈希图中。然后,我会显示食物相关词的得分最高者以及这些用户最常使用的食物词。
我目前的方法是通过空格来消除每一行文本,并使用 haystack 包含模式的 contains 方法(使用 indexOf 方法和朴素的子字符串搜索算法)处理 haystack 中的每个单独的单词。
wordFromInput.contains(wordFromPattern);
举个例子,有 17 个用户在聊天,13000 行文本,1600 种模式,我发现使用这种方法整个程序需要 12-13 秒。而在我正在开发的 Android 应用上,处理需要 2 分 30 秒,这太慢了。
最初,我尝试使用哈希映射并仅获取模式而不是在 ArrayList 中搜索它,但后来我意识到这是...
我想用子字符串做什么。
我通过 Stackoverflow 环顾四周,发现了很多有用且相关的问题,例如这两个:
1 和 2。我比较熟悉各种字符串算法(Boyer Moore、KMP 等)
我最初认为天真的方法对于我的情况当然是最糟糕的算法类型,但是找到this question,我意识到我的情况(短模式,短文本)实际上可能更多用朴素的方法有效。但我想知道是否有什么我完全忽略了。
这里是snippet of my code,但如果有人想更具体地了解我的问题。
虽然我删除了大部分代码以简化它,但我用来实际匹配子字符串的主要方法是在 matchWords() 方法中。
我知道那是非常丑陋和糟糕的代码(5 个 for 循环...),所以如果对此有任何建议,我也很高兴听到。
所以要清理它:
- 聊天记录中的文本行 (2000-10,000+),干草堆
- 1600 多种图案、针头
- 主要使用韩语字符,但也包含一些英文
- 蛮力幼稚方法实在是太慢了,但正在讨论是否有其他替代方案,即使有,考虑到短模式和文本的性质,它们是否实用。
我只是想要一些关于我的思考过程的意见,可能还有一些一般性的建议。但另外,如果可能的话,我想对特定算法或方法提出一些具体建议。
【问题讨论】:
-
java.util.regex
如何适应? -
对不起,因为我删除了很多matchWords()之外的部分,有很多东西可能看起来有点混乱。但我在开始时使用了正则表达式来消除句子中的空格,这样我就可以处理单个单词。编辑:还是你建议我使用 java.util.regex?
-
据我了解,这个问题可以说更适合程序员,因为它是一个白板讨论(而不是“为什么这段代码不起作用?”)。
-
我想知道正则表达式是否是一个可能的解决方案,但我还没有完全考虑你的问题。如果一开始就被排除在外,我不想考虑太多。
-
您是否考虑过使用像 en.wikipedia.org/wiki/… 这样的多模式匹配算法,或者为您的模式集构建一个通用的后缀树?
标签: java string algorithm substring