所以我试图在Java中搜索Arraylist并创建一个直方图,其中包含字符串与频率的长度,该长度存在于大型文本文件中。我想出了一个强力算法,但是它太慢而无法在大型数据文件中使用。是否有更有效的方式通过Arraylist进行处理?我已经提到了我提出的蛮力方法。
for (int i = 0; i < (maxLen + 1); i++)
{
int hit = 0;
for (int j = 0; j < list.size(); j++)
{
if (i == list.get(j).length())
++hit;
histogram[i] = hit;
}
}
答案 0 :(得分:2)
这非常低效。
如何而不是循环遍历每个可能的长度值,然后是每个可用的单词,只需循环遍历文档中的可用单词并计算它们的长度?
例如:
Map<Integer, Integer> frequencies = new HashMap<Integer, Integer>();
for(int i=0; i<list.size(); i++) {
String thisWord = list.get(i);
Integer theLength = (Integer)(thisWord.length());
if(frequencies.containsKey(theLength) {
frequencies.put(theLength, new Integer(frequencies.get(theLength).intValue()+1));
}
else {
frequencies.put(theLength, new Integer(1));
}
}
然后,如果HashMap
中不存在该密钥,则您知道文档中不存在该长度的单词。如果 键存在,您可以准确查找发生的次数。
注意:此代码示例的某些方面是为了防止任何有关装箱和拆箱的混淆。可以把它写得更清洁,我肯定会在生产环境中这样做。此外,它假设您不了解任何最小或最大字长(因此稍微更灵活,可扩展,并且全部都是如此)。否则,简单地声明原始数组的其他技术也可以正常工作(参见Jon Skeet的回答)。
对于利用自动装箱的更清洁版本:
Map<Integer, Integer> frequencies = new HashMap<Integer, Integer>();
for(int i=0; i<list.size(); i++) {
String thisWord = list.get(i);
if(frequencies.containsKey(thisWord.length()) {
frequencies.put(thisWord.length(), frequencies.get(thisWord.length())+1);
}
else {
frequencies.put(thisWord.length(), 1);
}
}
答案 1 :(得分:1)
为什么不循环遍历列表一次?
int[] histogram = new int[maxLen + 1]; // All entries will be 0 to start with
for (String text : list) {
if (text.length() <= maxLen) {
histogram[text.length()]++;
}
}
现在只是O(N)。