2011-01-21 58 views
2

可以说我有500个字:内存意识的字符串过滤

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

我有以下文字是关于85KB总数:

Marting去,让他自己的东西 从Hopa店面,现在他正在寻找 把它与他最好的 朋友Dunam存入存储。他们正在刨 使用戈拉普锁,他们发现在 Hugnog店在美孚镇。 >... 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. 您将如何获得统计信息,如替换了多少个单词和哪些单词;并为每个单词多少次被替换。
+0

您可以获取内存分析器来查看您使用的内存量。您可能需要500字来使用64 KB的内存。除非你使用手机来运行这个,否则你不需要担心。 – 2011-01-21 16:44:56

回答

3

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

  • 有包含所有字符串作为密钥的地图,随着时代的NUMER他们在文本(最初为0)
  • 读取字的文词,通过使用被发现一个StringTokenizer或String。分割()方法
  • 对于每个单词,查找映射是否包含它(O(1)操作,非常快)
  • 如果它包含它,则向StringBuilder添加“----”,并将值存储的单词在地图
  • 其他添加本身这个词(与前一个空间,除非它的文本的第一个字)的过程中

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

应该简单高效。

1

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

如果你知道你有大约500个单词,我建议将500个单词和它们的掩码存储在初始容量为650左右的HashMap中(JDK文档称散列效率最高,加载因子为0.75)。用for循环在HashMap中放入单词 - 掩码对。 (HashMap)你得到的最大回响是get/put操作(搜索关键字)在常量时间内完成,这比O(n)在数组中更好,甚至O(log( n))如果你对排序后的数组进行二分搜索。

用HashMap武装起来,你可以建立一个SringBuffer,同时过滤那些85KB的文本。 从你的方法返回String.toString(),你就完成了!问候, - M.S.

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

2

我不会在乎记忆太多,但如果你这样做:trie是你的朋友。它对于大型设备来说是高效的内存,并且可以非常有效地进行匹配你可能想要在compressed fashion中实现它。