首先,我想澄清一下,这个问题的性质与根据我的知识已经发布的其他问题不同。如果不是这样,请告诉我。
鉴于
问题
在给定时间,我将获得2个文件。我必须创建两个文件中常见的名称列表。
预处理
为了减少时间复杂度,我已经完成了预处理并对所有文件中的名称进行了排序。
我的方法
结果
现在每个文件中最多只有100行,而不是每个文件中有~3000(尽管平均值为400)。现在我将不得不检查公共组号,然后通过位操作的帮助我可以找到常用名称。
期望
任何人都可以建议更短更好的问题解决方案。我可以在我的应用程序中进行预处理和存储新文件,以便在查找通用名称时需要最少的处理。
如果我朝错误的方向解决问题,请告诉我。提前谢谢。
点
在我的方法中,总文件的大小为258KB(因为我使用了组名和组值),如果它在每行中按名称保存,则它的大小为573KB。这些文件必须存储在移动设备上。所以我需要尽可能减小尺寸。此外,我期待数据压缩,我不知道如何做到这一点。请注意解释。
答案 0 :(得分:4)
您是否尝试过以下操作?
如果您想要预处理一些额外的速度,请在每个列表中存储名称,并选择较短的列表作为list1。
答案 1 :(得分:2)
啊哈!鉴于您在编辑中声明的非常低的内存要求,您还可以做其他事情。
虽然我仍然认为你可以寻求其他答案的解决方案。具有3000 HashSet
个条目的String
不会太大。我对16-char Strings
的快速近似提示了低于400 kB的堆内存。试试吧,然后回去吧。这就像整个程序的25行代码。
如果解决方案占用太多内存,那么你可以这样做:
答案 2 :(得分:0)
您正在尝试使用列表重新实现Set。不要那样做。使用一组名称,这将自动处理插入的重复。
你需要阅读这两个文件,没有办法做到这一点。
// in pseudo-java
Set<String> names1 = new HashSet<String>();
for (String name : file1.getLine().trim()) {
names1.put(name);
}
Set<String> names2 = new HashSet<String>();
for (String name : file2.getLine().trim()) {
names2.put(name);
}
// with this line, names1 will discard any name not in names2
names1.retainAll(names2);
System.out.println(names1);
假设您使用HashSet
作为此示例,您将比较字符串的哈希值,这将显着提高性能。
如果您发现性能不足,则开始寻找更快的解决方案。其他任何 过早优化,如果你不知道它必须运行多快,那么它是优化而不设定目标。找到“最快”的解决方案需要枚举和耗尽每个可能的解决方案,因为您尚未检查的解决方案可能更快。
答案 3 :(得分:0)
我不确定我是否了解您的要求和情况。
你有大约2.500个文件,每个文件有3000个字(或400个?)。在多个文件中出现了许多重复的单词。
现在有人会问你,哪些单词有文件-345和文件-765的共同点。
您可以创建一个Hashmap,用于存储每个单词,以及一个文件列表,其中包含单词。
如果你得到文件345的3000字(400?),你可以在hashmap中查找,并查看列表中提到的文件765。
然而2 * 3000并不是那么多。如果我在Scala中创建2个字符串列表(在JVM上运行):
val g1 = (1 to 3000).map (x=> "" + r.nextInt (10000))
val g2 = (1 to 3000).map (x=> "" + r.nextInt (10000))
并建立交叉点
g1.intersect (g2)
我在8年前的笔记本电脑上几乎没有得到结果(678个元素)。
那么您需要回答多少次请求?文件输入多久更改一次?如果很少,那么读取2个文件可能是关键点。
你有多少独特的单词?也许将它们全部留在记忆中是没有问题的。