首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高级Java优化

高级Java优化
EN

Stack Overflow用户
提问于 2011-08-13 12:25:15
回答 6查看 2.3K关注 0票数 6

关于如何使用for、while和do-while循环进行低级Java优化,以及是否有必要这样做,有很多问题、答案和意见。

我的问题更多的是基于设计的高级优化。让我们假设我必须执行以下操作:

对于给定的字符串输入,计算字符串中每个字母的出现次数。

当字符串只有几个句子时,这不是一个大问题,但是如果我们想要计算一个900,000个单词文件中每个单词的出现次数,那该怎么办呢?构建循环只会浪费时间。

那么,可以应用于此类问题的高级设计模式是什么呢?

我想我的主要观点是,我倾向于使用循环来解决许多问题,并且我希望改掉使用循环的习惯。

提前感谢

相同的

附注:如果可能的话,你可以产生一些伪代码来解决900,000字的文件问题,我倾向于更好地理解代码比我能理解英语,我认为这是相同的大多数访问者的这个网站

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-08-13 12:43:27

Hadoop problem是大数据世界中复盖最广泛的问题之一;它类似于Hadoop等框架的Hello World。你可以在网上找到关于这个问题的大量信息。

不管怎样,我会给你一些想法。

首先,900000个单词可能仍然足够小,可以为其构建hashmap,因此不要忽视明显的内存中方法。你说伪代码很好,所以:

代码语言:javascript
复制
h = new HashMap<String, Integer>();
for each word w picked up while tokenizing the file {
  h[w] = w in h ? h[w]++ : 1
}

现在,一旦您的数据集太大而无法构建内存中的哈希图,您就可以像这样进行计数:

代码语言:javascript
复制
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标记输入的示例。下面是最简单的方法:

代码语言:javascript
复制
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());
        }
    } 
}

下面是一个使用它的示例:

代码语言:javascript
复制
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator

下面的输出

代码语言:javascript
复制
hey
moe!
woo
woo
woo
nyuk-nyuk
why
soitenly.
hey.

您可以将此标记器与sort和uniq结合使用,如下所示:

代码语言:javascript
复制
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator | sort | uniq

让位

代码语言:javascript
复制
hey
hey.
moe!
nyuk-nyuk
soitenly.
why
woo

现在,如果您只想保留字母并丢弃所有标点符号、数字和其他字符,请将扫描仪定义行更改为:

代码语言:javascript
复制
Scanner input = new Scanner(System.in).useDelimiter(Pattern.compile("\\P{L}"));

而现在

代码语言:javascript
复制
echo -e "Hey Moe! Woo\nwoo woo^nyuk-nyuk why#2soitenly. Hey." | java WordGenerator | sort | uniq

收益率

代码语言:javascript
复制
hey
moe
nyuk
soitenly
why
woo

输出中有一个空行;我将让您弄清楚如何删除它。:)

票数 10
EN

Stack Overflow用户

发布于 2011-08-13 12:41:58

最快的解决方案是O(n) AFAIK使用循环来迭代字符串,获取字符并相应地更新HashMap中的计数。最后,HashMap包含所有出现的字符和所有出现的字符的计数。

一些pseduo-code (可能无法编译)

代码语言:javascript
复制
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);
}
票数 3
EN

Stack Overflow用户

发布于 2011-08-13 12:45:19

你很难得到比使用循环解决这个问题更好的方法。为了加快这类操作的速度,最好的方法是将工作负载拆分为不同的工作单元,并使用不同的处理器处理这些工作单元(例如,如果您有一台多处理器计算机,则使用线程)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7048564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档