计算字符的Java面试题(haohao原创)
读了haohao的面试题l,发现自己对Java居然有陌生感了,觉得该补习一下,恢复一点感觉了。
做了一下测试。发现瓶颈在读数据的速度上。
package elib;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
public class CharTool3 {
private static void countChar(int[] charCounts,byte[] data) {
int tempCount = 0;
char c;
for(byte b:data) {
c = (char) b;
if (c >= 'a' && c <= 'z') {
tempCount = 25 - ('z' - c);
charCounts[tempCount]++;
continue;
}
if (c >= 'A' && c <= 'Z') {
tempCount = 25 - ('Z' - c);
charCounts[tempCount]++;
}
}
}
/* http://techrepublic.com.com/html/tr/sidebars/1046714-1.html */
public static byte[] read2array(String file) throws Exception {
InputStream in = null;
byte[] out = new byte[0];
try{
in = new BufferedInputStream(new FileInputStream(file));
// the length of a buffer can vary 20MB
int bufLen = 20000*1024;
byte[] buf = new byte[bufLen];
byte[] tmp = null;
int len = 0;
while((len = in.read(buf,0,bufLen)) != -1){
// extend array
tmp = new byte[out.length + len];
// copy data
System.arraycopy(out,0,tmp,0,out.length);
System.arraycopy(buf,0,tmp,out.length,len);
out = tmp;
tmp = null;
}
}finally{
// always close the stream
if (in != null) try{ in.close();}catch (Exception e){}
}
return out;
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
long begin = System.currentTimeMillis();
int[] charCounts = new int[26];
byte[] dat = new byte[0];;
try {
dat = read2array("/root/n.txt");
}catch(Exception e) {
System.out.println("Faile to read data");
}
System.out.println(dat.length);
countChar(charCounts, dat);
char c = 'a';
for(int ac:charCounts) {
if(ac>0){
System.out.print(c+"->");
System.out.println(ac);
}
c++;
}
System.out.println("执行时间" + (System.currentTimeMillis() - begin) + "ms");
}
}
测试数据是19Mb的英文小说《漂》,因大小不够,复制了6份左右合成。
但只有69104行,远不是标准的行。要haohao的原程序执行需要943MS,而修改后降为272MS,效率提升了大约3倍。
里面的代码除了haohao的,就是从http://techrepublic.com.com/html/tr/sidebars/1046714-1.html 搬过来的。
我做的工作只是COPY,测试。
还有String的toLowerCase()也影响效率,我给去掉了,这样大约能提升15%左右的速度。
a->1179608
b->223696
c->312432
.......
z->8472
原程序执行时间943ms,其中读文件时间700MS,按行读入并逐行计算。
文件大小:19084184(19Mb) 使用的读缓存20MB
a->1179608
b->223696
c->312432
......
x->14232
y->317792
z->8472
本程序执行时间272ms ,其中读文件时间仅90MS,读入全部数据后,集中计算。
19Mb的文本只有7万行,显然是不合标准的,如果是标准行,这2个程序的效率差距可能就更明显。数据量越大,一次读入相对分行处理的优势也会更明显。
t;352880
n->1001256
o->1053264
p->204624
q->10288
r->851344
s->913912
t->1293696
u->405400
v->122672
w->372888
x->14232
y->317792
z->8472
执行时间943ms
19084184
a->1179608
b->223696
c->312432
d->695720
e->1834320
f->286912
g->317880
h->983560
i->876384
j->16144
k->148032
l->641448
m->352880
n->1001256
o->1053264
p->204624
q->10288
r->851344
s->913912
t->1293696
u->405400
v->122672
w->372888
x->14232
y->317792
z->8472
执行时间272ms
x->14232
y->317792
z->8472
执行时间272ms
做了一下测试。发现瓶颈在读数据的速度上。
package elib;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
public class CharTool3 {
private static void countChar(int[] charCounts,byte[] data) {
int tempCount = 0;
char c;
for(byte b:data) {
c = (char) b;
if (c >= 'a' && c <= 'z') {
tempCount = 25 - ('z' - c);
charCounts[tempCount]++;
continue;
}
if (c >= 'A' && c <= 'Z') {
tempCount = 25 - ('Z' - c);
charCounts[tempCount]++;
}
}
}
/* http://techrepublic.com.com/html/tr/sidebars/1046714-1.html */
public static byte[] read2array(String file) throws Exception {
InputStream in = null;
byte[] out = new byte[0];
try{
in = new BufferedInputStream(new FileInputStream(file));
// the length of a buffer can vary 20MB
int bufLen = 20000*1024;
byte[] buf = new byte[bufLen];
byte[] tmp = null;
int len = 0;
while((len = in.read(buf,0,bufLen)) != -1){
// extend array
tmp = new byte[out.length + len];
// copy data
System.arraycopy(out,0,tmp,0,out.length);
System.arraycopy(buf,0,tmp,out.length,len);
out = tmp;
tmp = null;
}
}finally{
// always close the stream
if (in != null) try{ in.close();}catch (Exception e){}
}
return out;
}
@SuppressWarnings("unchecked")
public static void main(String[] args) {
long begin = System.currentTimeMillis();
int[] charCounts = new int[26];
byte[] dat = new byte[0];;
try {
dat = read2array("/root/n.txt");
}catch(Exception e) {
System.out.println("Faile to read data");
}
System.out.println(dat.length);
countChar(charCounts, dat);
char c = 'a';
for(int ac:charCounts) {
if(ac>0){
System.out.print(c+"->");
System.out.println(ac);
}
c++;
}
System.out.println("执行时间" + (System.currentTimeMillis() - begin) + "ms");
}
}
测试数据是19Mb的英文小说《漂》,因大小不够,复制了6份左右合成。
但只有69104行,远不是标准的行。要haohao的原程序执行需要943MS,而修改后降为272MS,效率提升了大约3倍。
里面的代码除了haohao的,就是从http://techrepublic.com.com/html/tr/sidebars/1046714-1.html 搬过来的。
我做的工作只是COPY,测试。
还有String的toLowerCase()也影响效率,我给去掉了,这样大约能提升15%左右的速度。
a->1179608
b->223696
c->312432
.......
z->8472
原程序执行时间943ms,其中读文件时间700MS,按行读入并逐行计算。
文件大小:19084184(19Mb) 使用的读缓存20MB
a->1179608
b->223696
c->312432
......
x->14232
y->317792
z->8472
本程序执行时间272ms ,其中读文件时间仅90MS,读入全部数据后,集中计算。
19Mb的文本只有7万行,显然是不合标准的,如果是标准行,这2个程序的效率差距可能就更明显。数据量越大,一次读入相对分行处理的优势也会更明显。
t;352880
n->1001256
o->1053264
p->204624
q->10288
r->851344
s->913912
t->1293696
u->405400
v->122672
w->372888
x->14232
y->317792
z->8472
执行时间943ms
19084184
a->1179608
b->223696
c->312432
d->695720
e->1834320
f->286912
g->317880
h->983560
i->876384
j->16144
k->148032
l->641448
m->352880
n->1001256
o->1053264
p->204624
q->10288
r->851344
s->913912
t->1293696
u->405400
v->122672
w->372888
x->14232
y->317792
z->8472
执行时间272ms
x->14232
y->317792
z->8472
执行时间272ms
hofman
2008-08-05 03:48:54
评论:0
阅读:57
引用:0
