记忆意识字符串过滤

时间:2011-01-21 16:38:24

标签: java string filter replace

让我说我有500个字:

Martin
Hopa
Dunam
Golap
Hugnog
Foo
... + 494 more words

我有以下大约85KB的文字:

  

Marting 去了他自己的东西   来自 Hopa 商店,现在他正在寻找   用他最好的方式把它存放起来   朋友 Dunam 。他们正在刨   使用他们找到的 Golap 锁   Hugnog在 Foo 镇购物。 >... text continues into several pages

我想提供以下文字:

  

------- 去找他自己的东西   来自 ---- 商店,现在他正在寻找   用他最好的方式把它存放起来   朋友 ---- 。他们正在刨   使用他们找到的 ---- 锁定    ------ --- 小镇购物。 >... text continues into several pages

目前我正在使用公共方法:

String[] 500words = //all 500 words
String[] maskFor500words = // generated mask for each word
String filteredText = StringUtils.replaceEach(textToBeFiltered, 500words , maskFor500words);
  1. 还有另一种方法可以在内存和CPU使用方面提高效率吗?
  2. 500字的最佳存储空间是什么?文件,列表,枚举,数组......?
  3. 您如何获得统计数据,例如更换了多少和哪些单词;并且每个单词被替换了多少次。

3 个答案:

答案 0 :(得分:3)

我不太关心CPU和内存的使用情况。对于这样的问题和如此大量的文本,它应该相对较小。 我会做的是

  • 有一个包含所有字符串作为键的Map,其中包含在文本中找到它们的数量(最初为0)
  • 逐字逐句阅读文本,使用StringTokenizer或String.split()方法
  • 对于每个单词,查找地图是否包含它(O(1)操作,非常快)
  • 如果它包含它,将“----”添加到StringBuilder,并增加为地图中的单词存储的值
  • 否则添加单词本身(前面有空格,除非它是文本的第一个单词)

在过程结束时,StringBuilder包含结果,并且地图包含每个单词用作替换的次数。 确保使用原始文本的长度初始化STringBuilder,以避免重新分配太多。

应该简单而有效。

答案 1 :(得分:2)

我不太关心记忆,但万一你这样做:trie是你的朋友。它对于大型集合而言是高效的内存,并且可以实现非常高效的匹配。您可能希望在compressed fashion

中实现它

答案 2 :(得分:1)

如果我正确理解了这个问题,你需要阅读85KB的文本并解析每个单词(使用split或StringTokenizer)。对于每个单词,您需要知道是否在500字的集合中使用它,如果是,请使用相应的掩码进行切换。

如果您知道大约有500个单词,我建议将500个单词及其掩码存储在HashMap中,初始容量约为650(JDK doc表示散列最有效,加载因子为0.75)。使用for循环放入HashMap中的字掩码对。

你得到的最大轰动(HashMap)是get / put操作(搜索键)是在恒定时间内完成的,这比数组中的O(n)更好,甚至是O(log(n) ))如果你对已排序的数组进行二进制搜索。

使用HashMap,您可以在过滤85KB文本时构建SringBuffer。 从你的方法返回String.toString(),你就完成了!问候, - M.S。

PS如果您正在服务器上构建地图并在其他地方(在客户端)进行过滤并需要传输字典,HashMap将不会这样做 - 它无法序列化。在这种情况下使用Hashtable。如果在同一台机器上,HashMap的内存效率更高。后来, - M.S。