是否对我来说,使用Java indexOf(暴力方法)或其他一些子字符串算法更实用?

15 浏览
0 Comments

是否对我来说,使用Java indexOf(暴力方法)或其他一些子字符串算法更实用?

我正在寻找在许多短文本行(haystack)中找到非常短的子字符串(pattern,needle)。然而,我不太确定除了朴素的暴力方法之外应该使用哪种方法。

背景:我正在做一个有趣的副业项目,我接收多个用户的短信聊天记录(文本行数为2000-15000行,用户数为2-50个),并希望根据我提前确定的词语在聊天记录中找到所有各种模式匹配。到目前为止,我有大约1600个我正在寻找的模式,但我可能会寻找更多。

例如,我想找出在平均文本消息记录中使用的与食物相关的单词数量,如“汉堡包”,“比萨饼”,“可乐”,“午餐”,“晚餐”,“餐厅”,“麦当劳”。虽然我给出了英文示例,但实际上我将在我的程序中使用韩文。每个指定的单词都将有自己的分数,我将它们分别放在一个哈希映射中作为键和值。然后,我展示与食物相关的单词的最高得分者以及这些用户在食物单词中使用最频繁的词语。

我的当前方法是通过空格消除每行文本,并使用contains方法(使用indexOf方法和朴素的子字符串搜索算法)处理来自haystack的每个单词,如果haystack包含pattern,则返回true。

举个例子,对于17个聊天用户、13000行文本和1600个模式,我发现使用这种方法,整个程序需要12-13秒。在我正在开发的Android应用程序中,处理这些数据需要2分30秒,速度太慢了。

最初,我尝试使用哈希映射仅获取模式,而不是在ArrayList中搜索模式,但我后来意识到这对于我正在尝试使用子字符串做的事情来说是不可能的。

我在Stackoverflow上寻找到了很多有用和相关的问题,例如这两个:

1 和 2。我对各种字符串算法(Boyer Moore,KMP等)有些了解。

我最初认为朴素方法当然是对我的情况最糟糕的算法类型,但是在找到这个问题之后,我意识到我的情况(短模式,短文本)实际上可能更适合朴素方法。但我想知道是否有其他我完全忽视的东西。

如果有人想要更具体地了解我的问题,这里有一段我的代码片段。

虽然我删除了大部分代码以简化它,但我用于实际匹配子字符串的主要方法在matchWords()方法中。

我知道这是非常丑陋和糟糕的代码(5个循环...),所以如果有任何建议,我很乐意听取。

因此,为了整理一下:

- 聊天记录的文本行(2000-10,000+),haystack

- 1600+个模式,needle(s)

- 主要使用韩文字符,但包含一些英文

- 暴力朴素方法速度太慢,但我在考虑是否有其他选择,即使有其他选择,是否在短模式和文本的性质下是实用的。

我只是希望对我的思路有一些意见,可能还有一些建议。但是另外,如果可能的话,我希望得到一些特定的算法或方法的具体建议。

0
0 Comments

问题的原因是提问者需要在一个字符串中查找一组字符串的所有匹配项,并且希望能够以线性时间复杂度完成。提问者询问是否应该使用Java的indexOf(暴力方法)或其他子字符串算法来解决这个问题。

解决方法是使用Aho-Corasick字符串匹配算法。该算法可以在源字符串中找到一组模式字符串的所有匹配项,并且可以在线性时间内完成(加上报告匹配项的时间)。如果要搜索的字符串集是固定的,可以在模式上进行线性预处理,以便快速搜索所有匹配项。

这里有一个Java实现的Aho-Corasick算法可用。虽然我没有尝试过,但它可能是一个很好的选择。

希望这可以帮到你!

0
0 Comments

在这段内容中,问题的出现是因为作者希望在字符串中查找多个模式,而Java的string.contains方法只能用于查找单个模式。解决方法之一是使用正则表达式来匹配所有的模式,这样可以在一次匹配中找到所有的模式,而不是逐个查找。创建一个包含所有模式的正则表达式,编译它并进行匹配,这样可以提高匹配速度。另一种解决方法是使用一种算法,该算法需要对模式进行一次预处理,然后在任何给定输入的情况下,可以在O(n)的时间复杂度内找到任何模式的所有出现。与使用传统的字符串匹配算法相比,这种方法可以大大提高匹配速度。

文章整理如下:

对于在字符串中查找多个模式的需求,Java的string.contains方法并不适用。为了提高匹配速度,有两种解决方法可以选择。一种方法是使用正则表达式,创建一个包含所有模式的正则表达式,并进行编译和匹配。这样可以一次匹配找到所有模式,而不是逐个查找。另一种方法是使用一种算法,该算法需要对模式进行一次预处理,然后可以在任何给定输入的情况下,以O(n)的时间复杂度找到任何模式的所有出现。与传统的字符串匹配算法相比,这种方法可以显著提高匹配速度。具体的实现可以根据具体情况选择使用正则表达式还是算法预处理的方式来查找多个模式。通过尝试不同的方法,可以评估它们的性能并选择最合适的方法。

0
0 Comments

原因:问题的提出是因为需要在给定的文本中查找子字符串。目前使用的方法是使用Java的indexOf方法进行暴力搜索,但是否有更实用的子字符串算法是一个疑问。

解决方法:根据讨论中的建议,可以使用Trie数据结构来替代哈希表。首先,将文本按照空格分割成单词,然后检查单词是否在Trie中。如果在Trie中找到了单词,就更新与该单词关联的计数器。理想情况下,计数器应该集成到Trie中。这种方法的时间复杂度是O(C),其中C是文本中的字符数。由于很难避免至少检查每个字符一次,因此这种方法至少在时间复杂度方面是最好的选择。

然而,根据讨论中的意见,可能并不想列出所有可能的搜索词。因此,可以使用所有单词构建一个计数Trie。这样做可能会使任何模式匹配算法更容易。尽管如此,这可能需要对Trie进行一些修改。

此外,还提到了使用广义后缀树/ Aho-Corasick自动机的方法。这种方法可以在O(n)的时间复杂度下解决查询问题,并且可以进行真正的子字符串搜索(无需标记化)。还可以对匹配项进行聚合计算,如匹配计数或与匹配项相关的总分数。然而,由于该算法的实现可能具有较大的空间开销,因此在讨论中并未详细讨论。

最后,提出者承认自己不熟悉广义后缀树/ Aho-Corasick自动机算法,并且没有将其扩展成几乎相同的算法,因为在编写时还不清楚是否需要,并且可能具有显着的空间开销。然而,进一步研究后,发现该算法似乎非常适合这个问题。

0