1

我正在用Java实现这个。

Symbol file     Store data file

1\item1         10\storename1
10\item20       15\storename6
11\item6        15\storename9
15\item14       1\storename250
5\item5         1\storename15

用户将使用通配符搜索商店名称,例如storename? 我的工作是搜索商店名称并使用符号数据生成完整的字符串。例如:

item20-storename1
item14-storename6
item14-storename9

我的做法是:

  1. 逐行读取存储数据文件
  2. 如果任何行包含匹配的搜索字符串(如storename?),我会将该行推送到中间存储结果文件
  3. 我还将匹配商店名称的 itemno 复制到数组列表中(如 10,15)
  4. 当这个 arraylist size%100==0 时,我将使用 hashset 删除重复的项目号,显着减小 arraylist 大小
  5. 当arraylist大小> 1000

    1. 使用排序该列表Collections.sort(itemno_arraylist)
    2. 打开符号文件并开始逐行读取
    3. 对于每一行Collections.binarySearch(itemno_arraylist,itmeno)
    4. 如果匹配则将结果推送到中间符号结果文件
  6. 继续步骤1,直到存储数据文件的EOF

...

在这一切之后,我将结合两个结果文件(符号结果文件和存储结果文件)来呈现实际的字符串列表。

这种方法是有效的,但它会消耗更多的 CPU 时间和主内存。

我想知道一个更好的解决方案,减少 CPU 时间(目前为 2 分钟)和内存(目前为 80MB)。Java 中有许多可用的集合类。哪一个会为这种巨大的字符串处理问题提供更有效的解决方案?

如果您对这种字符串处理问题有任何想法,那么在 Java 中也会非常有用。

注意:这两个文件的长度接近一百万行。

4

4 回答 4

4

用嵌入式数据库替换这两个平面文件(有很多,我过去使用 SQLite 和 Db4O):问题解决了。

于 2012-10-21T07:03:43.703 回答
1

所以你需要替换10\storename1为,item20-storename1因为符号文件包含10\item20. 显而易见的解决方案是将符号文件加载到 Map 中:

String tokens=symbolFile.readLine().split("\\");
map.put(tokens[0], tokens[1]);

然后逐行读取存储文件并替换:

String tokens=storelFile.readLine().split("\\");
output.println(map.get(tokens[0])+'-'+tokens[1]));

这是最快的方法,但仍会为地图使用大量内存。您可以减少将地图存储在数据库中的内存,但这会显着增加时间。

于 2012-10-21T07:18:38.273 回答
0

使用地图有什么限制吗?您可以将项目添加到地图,然后您可以轻松搜索?100 万条记录意味着 1M * 记录大小,因此不会有问题。

   Map<Integer,Item> itemMap= new HashMap();
   ...
   Item item= itemMap.get(store.getItemNo());

但是,最好的解决方案是使用数据库。

于 2012-10-21T07:10:31.613 回答
0

如果您的输入数据文件不经常更改,则解析文件一次,将数据放入List自定义类中,例如FileStoreRecord将您的记录映射到文件中。在您的自定义类上定义一个equals方法。List对例如搜索执行所有后续步骤,您可以contains通过以自定义对象的形式传递搜索字符串来调用方法FileStoreRecord

如果文件在一段时间后发生变化,您可能需要List在特定间隔后刷新或跟踪列表创建时间并在使用前与文件更新时间戳进行比较。如果有不同,请重新创建列表。管理文件检查的另一种方法可能是让线程不断轮询文件更新,并且在文件更新的那一刻,它通知刷新列表。

于 2012-10-21T06:48:28.850 回答