计算字符的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
hofman   2008-08-05 03:48:54 评论:0   阅读:57   引用:0

发表评论>>

署名发表(评论可管理,不必输入下面的姓名)

姓名:

主题:

内容: 最少15个,最长1000个字符

验证码: (如不清楚,请刷新)

2003-2007@copyright