我正在用java编写一个程序来获取一个非常大的字符串(string s <= 100000)中单词的统计数据。这应该需要不到1秒的时间,并且使用少于16MB的内存。
import java.util.Scanner;
class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String t = sc.nextLine();
int i=0;
while(t.charAt(i)==' ') i++;
t = t.substring(i);
String[] s = t.split(" +");
RecString[] stat = new RecString[s.length];
for(i=0; i<s.length;i++){
stat[i] = new RecString("");
}
int j=0;
for(i=0; i<s.length;i++){
int f=0;
for(int h =0; h<stat.length; h++){
if(stat[h].word.equals(s[i])){
f = 1;
stat[h].count++;
break;
}
}
if(f==0){
stat[j] = new RecString(s[i]);
j++;
}
}
for(i=0;i<=j;i++){
if(stat[i].word != ""){
System.out.println(stat[i].word+" "+(stat[i].count));
}
}
}
}
class RecString{
public String word;
public int count;
public RecString(String s){
word = s;
count = 1;
}
}
此代码适用于长度为<=255的字符串,但对于大字符串,我有时间或/和内存限制。
请帮我优化我的程序
发布于 2013-04-14 14:57:19
如果你关心内存,你会想要尝试尽可能多地流传输。
请参阅http://docs.oracle.com/javase/6/docs/api/java/io/StreamTokenizer.html
StreamTokenizer tokenizer = new StreamTokenizer(new InputStreamReader(System.in));
while(tokenizer.nextToken() != StreamTokenizer.TT_EOF){
if(tokenizer.ttype == StreamTokenizer.TT_WORD) {
// found a word.
System.out.println(tokenizer.sval);
}
}
当然,如果内存不是问题,速度是您唯一关心的问题,那么Hadoop有一个很好的单词计数示例:http://wiki.apache.org/hadoop/WordCount。但是把它留到学习的不时之需。
此外,你的计算单词的逻辑对于效率(它的O(N)
)是不正确的。@DaveNewton是正确的,你可能应该使用一个Map<String,Integer>
,它会给你一个O(1)
,而不是你的RecString
数组。我不打算纠正你的结论,因为我认为这是一个很好的练习。
https://stackoverflow.com/questions/16000175
复制