关于如何使用for、while和do-while循环进行低级Java优化,以及是否有必要这样做,有很多问题、答案和意见。
我的问题更多的是基于设计的高级优化。让我们假设我必须执行以下操作:
对于给定的字符串输入,计算字符串中每个字母的出现次数。
当字符串只有几个句子时,这不是一个大问题,但是如果我们想要计算一个900,000个单词文件中每个单词的出现次数,那该怎么办呢?构建循环只会浪费时间。
那么,可以应用于此类问题的高级设计模式是什么呢?
我想我的主要观点是,我倾向于使用循环来解决许多问题,并且我希望改掉使用循环的习惯。
提前感谢
相同的
附注:如果可能的话,你可以产生一些伪代码来解决900,000字的文件问题,我倾向于更好地理解代码比我能理解英语,我认为这是相同的大多数访问者的这个网站
发布于 2011-08-13 12:43:27
Hadoop problem是大数据世界中复盖最广泛的问题之一;它类似于Hadoop等框架的Hello World。你可以在网上找到关于这个问题的大量信息。
不管怎样,我会给你一些想法。
首先,900000个单词可能仍然足够小,可以为其构建hashmap,因此不要忽视明显的内存中方法。你说伪代码很好,所以:
h = new HashMap<String, Integer>();
for each word w picked up while tokenizing the file {
h[w] = w in h ? h[w]++ : 1
}现在,一旦您的数据集太大而无法构建内存中的哈希图,您就可以像这样进行计数:
Tokenize into words writing each word to a single line in a file
Use the Unix sort command to produce the next file
Count as you traverse the sorted file这三个步骤在Unix管道中进行。在这里,让操作系统为您完成工作。
现在,当您获得更多数据时,您希望引入hadoop等map-reduce框架来对机器集群进行单词计数。
现在,我听说当你进入一个令人讨厌的大型数据集时,在分布式环境中做事情不再有帮助,因为传输时间超过了计数时间,在你的单词计数的情况下,所有的东西都必须“无论如何都要放在一起”,所以你必须使用一些非常复杂的技术,我怀疑你可以在研究论文中找到这些技术。
附录
OP要求提供一个使用Java标记输入的示例。下面是最简单的方法:
import java.util.Scanner;
public class WordGenerator {
/**
* Tokenizes standard input into words, writing each word to standard output,
* on per line. Because it reads from standard input and writes to standard
* output, it can easily be used in a pipeline combined with sort, uniq, and
* any other such application.
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
System.out.println(input.next().toLowerCase());
}
}
}下面是一个使用它的示例:
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator下面的输出
hey
moe!
woo
woo
woo
nyuk-nyuk
why
soitenly.
hey.您可以将此标记器与sort和uniq结合使用,如下所示:
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator | sort | uniq让位
hey
hey.
moe!
nyuk-nyuk
soitenly.
why
woo现在,如果您只想保留字母并丢弃所有标点符号、数字和其他字符,请将扫描仪定义行更改为:
Scanner input = new Scanner(System.in).useDelimiter(Pattern.compile("\\P{L}"));而现在
echo -e "Hey Moe! Woo\nwoo woo^nyuk-nyuk why#2soitenly. Hey." | java WordGenerator | sort | uniq收益率
hey
moe
nyuk
soitenly
why
woo输出中有一个空行;我将让您弄清楚如何删除它。:)
发布于 2011-08-13 12:41:58
最快的解决方案是O(n) AFAIK使用循环来迭代字符串,获取字符并相应地更新HashMap中的计数。最后,HashMap包含所有出现的字符和所有出现的字符的计数。
一些pseduo-code (可能无法编译)
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (map.containsKey(c)) map.put(c, map.get(c) + 1);
else map.put(c, 1);
}发布于 2011-08-13 12:45:19
你很难得到比使用循环解决这个问题更好的方法。为了加快这类操作的速度,最好的方法是将工作负载拆分为不同的工作单元,并使用不同的处理器处理这些工作单元(例如,如果您有一台多处理器计算机,则使用线程)。
https://stackoverflow.com/questions/7048564
复制相似问题