2009年11月22日 星期日

ibus recovery from "no input window " error

fedora11預設安裝文字輸入系統為ibus,
於繁體中文語言登入時,ibus預設有注音及拼音兩者可正常使用,
但若用[系統/管理/新增/移除軟體]添加倉頡等輸入法,
則安裝好後,所有輸入法都會消失,只顯示"no input window"訊息.

原因可能是安裝倉頡時連帶更新的ibus-1.2有bug,
還原ibus-1.1舊設定法為
# rpm -qa | grep ibus- (先看目前裝了那些ibus套件)
# ln -s /media/Fedora\ 11\ i386\ DVD/Packages/* /var/cache/yum/fedora/packages/
(將安裝光碟套件作成捷徑,放入yum cache套件目錄中,省去再從網路抓)
# yum downgrade ibus-libs (讓yum自動檢查移除ibus-1.2相關套件,並退回ibus-libs 1.1)
Running Transaction
Installing : ibus-libs-1.1.0.20090423-1.fc11.i586 1/12
Erasing : ibus-1.2.0.20090927-1.fc11.i586 2/12
Erasing : ibus-gtk-1.2.0.20090927-1.fc11.i586 3/12
Erasing : ibus-chewing-1.2.0.20091002-1.fc11.i586 4/12
Cleanup : ibus-libs-1.2.0.20090927-1.fc11.i586 5/12
Erasing : ibus-rawcode-1.2.0.20090703-1.fc11.i586 6/12
Erasing : ibus-m17n-1.2.0.20090617-2.fc11.i586 7/12
Erasing : ibus-table-cangjie-1.2.0.20090717-2.fc11.noarch 8/12
Erasing : ibus-hangul-1.2.0.20090617-2.fc11.i586 9/12
Erasing : ibus-table-1.2.0.20091014-2.fc11.noarch 10/12
Erasing : ibus-anthy-1.1.0.20090402-1.fc11.i586 11/12
Erasing : ibus-pinyin-1.1.0.20090303-1.fc11.noarch 12/12
# yum localinstall ibus-1.1.0.20090423-1.fc11.i586.rpm
# yum localinstall ibus-chewing-1.0.10.20090523-2.fc11.i586.rpm
# yum localinstall ibus-pinyin-1.1.0.20090303-1.fc11.noarch.rpm
# yum localinstall ibus-gtk-1.1.0.20090423-1.fc11.i586.rpm
然後[系統/關機/重新啟動]
帳號登入後,再按[Ctrl-space]啟動,按[Alt+Left_SHIFT]切換,
就可看到原來的拼音及注音語言輸入列.

當然,添加的倉頡等輸入法也都跟著消失.
解決法大概只有
1.安裝依存於舊版ibus-1.1之倉頡版本.
2.乾脆不用ibus而改用原來另外一種輸入法scim.
(yum install scim-python-xingma-cangjie.i586)

vmware server 1.0.6 on centos5.4 x86_64

在64位元centos5.4上,vmware server和xen核心不相容,裝得起來,但是執行vmware會當掉.
故要在如下centos5.4上利用vmware server建立虛擬機,

[user@centos ~]$ uname -a
Linux centos.im.tku.edu.tw 2.6.18-164.6.1.el5 #1 SMP Tue Nov 3 16:12:36 EST 2009
x86_64 x86_64 x86_64 GNU/Linux

測試可行安裝清單如下,

kernel-2.6.18-164.6.1.el5
kernel-devel-2.6.18-164.6.1.el5 (vmware編譯所需核心宣告檔)
VMware-server-1.0.6-91891.tar.gz (需重新自動編譯)

-- 以下清單為有需要才安裝 --
ntfs-3g-200944-e1i686.rpm (有讀寫ntfs切割才安裝,但是無法作檔案鎖定,無法跑vmware)
NVDIA-Linux-x86_64-185.18.31-pkg2.run (有geforce顯示卡才安裝,需telinit 3下,自動編譯)

2009年11月21日 星期六

tomcat6 encoding problem by GET/POST


撰寫jsp時,使用tomcat6引擎,常見接收中文出現亂碼,不像使用resin引擎方便,
這時只要作如下兩tomcat組態檔修改,
就可以接收表單的GET方式送來的中文big5碼,轉換成jsp內建的unicode.
這樣很方便作中文碼參數置入網址之測試,例如,http://host/cgi?q=%ac%ec.

/etc/tomcat6/server.xml

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="big5" />


/etc/tomcat6/web.xml

<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>parameterEncoding</param-name>
<param-value>big5</param-value>
</init-param>

</servlet>

另外,發覺瀏覽器使用GET方式封裝中文參數於網址時,
有時會用big5,有時會用utf-8,視網頁如下宣告編碼(charset)而定,
<%@page contentType="text/html; charset=big5" import="java.io.*" %>
但作了如上2組態檔設定後,就只有big5送來的碼可正常轉換成unicode碼.
註:原來tomcat預設只接收"iso-8859-1"正常ascii編碼之參數.

至於表單用POST方式送來的big5中文碼參數,要正確轉換成unicode,
則.jsp程式碼需加上如下設定編碼指令才行.
request.setCharacterEncoding("big5");
query = request.getParameter("q");

參考資料:
http://minchuanwang.blogspot.com/2009/03/tomcat-post-get.html

2009年10月29日 星期四

simple notes on libsvm java

libsvm java版使用例
==================
                                             
1.libsvm程式下載點:
  http://www.csie.ntu.edu.tw/~cjlin/libsvm+zip

2.範例資料下載點:
  http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets

3.程式編譯法:
C:\libsvm\libsvm-2.89\java>javac -cp libsvm.jar *.java
產生尺度調整器svm_scale.class
    訓練器svm_train.class
    預測器svm_predict.class

4.資料採稀疏格式,一列一案例,先預測數值,再列舉所有非零(維度:值)

5.訓練測試範例
  以下範例訓練集資料: a1a.txt
  以下範例測試集資料: a1a_t.txt

A.未作尺度調整例:
A1.呼叫訓練器
    輸入訓練資料: a1a.txt
    輸出學得模型: a1a_model.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_train a1a.txt a1a_model.txt
*
optimization finished, #iter = 495
nu = 0.46026768501985826
obj = -673.0313934890871, rho = -0.6285688589260043
nSV = 754, nBSV = 722
Total nSV = 754

A2.呼叫預測器
    輸入測試資料: a1a_t.txt
    輸入學得模型: a1a_model.txt
    輸出預測結果: a1a_predict.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_predict a1a_t.txt a1a_model.txt a1a_predict.txt
Accuracy = 83.58638066933712% (25875/30956) (classification)
--
B.作尺度調整例:
B1.呼叫尺度調整器2次
     輸入訓練資料:     a1a.txt
     輸出調整模型:     a1a_param.txt
     輸出調整訓練資料: a1a_scale.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_scale -s a1a_param.txt a1a.txt > a1a_scale.txt
Warning: original #nonzeros 22249
         new      #nonzeros 181365
Use -l 0 if many original feature values are zeros

     輸入測試資料:     a1a_t.txt
     輸入調整模型:     a1a_param.txt
     輸出調整測試資料: a1a_t_scale.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_scale -r a1a_param.txt a1a_t.txt > a1a_t_scale.txt
Warning: original #nonzeros 429343
         new      #nonzeros 3807588
Use -l 0 if many original feature values are zeros

B2.呼叫訓練器
    輸入訓練資料: a1a_scale.txt
    輸出學得模型: a1a_model_scale.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_train a1a_scale.txt
 a1a_model_scale.txt
*
optimization finished, #iter = 682
nu = 0.4077289259698594
obj = -593.6459193183854, rho = -0.48104500731367267
nSV = 694, nBSV = 622
Total nSV = 694

B3.呼叫預測器
    輸入測試資料: a1a_t_scale.txt
    輸入學得模型: a1a_model_scale.txt
    輸出預測結果: a1a_predict_scale.txt
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_predict a1a_t_scale
.txt a1a_model_scale.txt a1a_predict_scale.txt
Accuracy = 84.05478744023776% (26020/30956) (classification)

--
-- 以上B相對於A,多作了輸出入範圍尺度調整,準確率略提昇.
-- 另外,A1及B2呼叫訓練器時,針對預設C-SVC學習器,
-- 若能適當作參數網格搜尋最佳化,準確率會更提昇
-- C-SVC參數有-g gamma及-c cost兩項,詳libsvm首頁guide.pdf
--  http://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf
--
1. 尺度調整器選項:
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_scale
Usage: svm-scale [options] data_filename
options:
-l lower : x scaling lower limit (default -1)
-u upper : x scaling upper limit (default +1)
-y y_lower y_upper : y scaling limits (default: no y scaling)
-s save_filename : save scaling parameters to save_filename
-r restore_filename : restore scaling parameters from restore_filename

2. 訓練器選項:
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_train
Usage: svm_train [options] training_set_file [model_file]
options:
-s svm_type : set type of SVM (default 0)
        0 -- C-SVC
        1 -- nu-SVC
        2 -- one-class SVM
        3 -- epsilon-SVR
        4 -- nu-SVR
-t kernel_type : set type of kernel function (default 2)
        0 -- linear: u'*v
        1 -- polynomial: (gamma*u'*v + coef0)^degree
        2 -- radial basis function: exp(-gamma*|u-v|^2)
        3 -- sigmoid: tanh(gamma*u'*v + coef0)
        4 -- precomputed kernel (kernel values in training_set_file)
-d degree : set degree in kernel function (default 3)
-g gamma : set gamma in kernel function (default 1/k)
-r coef0 : set coef0 in kernel function (default 0)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
-m cachesize : set cache memory size in MB (default 100)
-e epsilon : set tolerance of termination criterion (default 0.001)
-h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)
-b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
-wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)
-v n : n-fold cross validation mode
-q : quiet mode (no outputs)

3. 預測器選項:
C:\libsvm\libsvm-2.89\java>java -cp libsvm.jar svm_predict
usage: svm_predict [options] test_file model_file output_file
options:
-b probability_estimates: whether to predict probability estimates, 0 or 1 (default 0); one-class SVM not supported yet

2009年7月21日 星期二

code for testing if two line segments are intersecting


/*
   Line.java

     Test if two line segments are intersecting or not
     Line segment 1 is between endpoints (x1,y1) and (x2,y2)
     Line segment 2 is between endpoints (u1,v1) and (u2,v2)

   Usage: java Line x1 y1 x2 y2 u1 v1 u2 v2

   > java Line
   java Line 0 1 1 0 0 0 1 1

   > java Line 0 1 1 0 0 0 1 1
    t * 1.000000 = 0.000000 + u * 1.000000
    t * -1.000000 = -1.000000 + u * 1.000000
    ---
    t * 1.000000 = 0.000000 + u * 1.000000
    t * -1.000000 = -1.000000 + u * 1.000000
    ---
    t = nom(1.000000) / denom(2.000000) = 0.500000
    u = nom(-1.000000) / denom(-2.000000) = 0.500000
   true
*/
public class Line
{
  //  line1:  0 <= t <= 1
  // x = ax1 + t * (ax2 - ax1)
  //    y = ay1 + t * (ay2 - ay1)

  //  line2:  0 <= u <= 1
  // x = bx1 + u * (bx2 - bx1)
  //    y = by1 + u * (by2 - by1)

  //  returns true if two lines intersect; and false otherwise

  public static boolean isTwoLinesIntersecting(
    double ax1, double ay1, double ax2, double ay2,
    double bx1, double by1, double bx2, double by2)
  {
    double nom, denom;
    double ax21 = ax2 - ax1;
    double bax1 = bx1 - ax1;
    double bx21 = bx2 - bx1;
    double ay21 = ay2 - ay1;
    double bay1 = by1 - ay1;
    double by21 = by2 - by1;

    // t * (ax2 - ax1) = (bx1 - ax1) + u * (bx2 - bx1)
    // t * (ay2 - ay1) = (by1 - ay1) + u * (by2 - by1)
     System.out.printf(" t * %f = %f + u * %f\n", ax21, bax1, bx21);
     System.out.printf(" t * %f = %f + u * %f\n", ay21, bay1, by21);
     System.out.printf(" ---\n");

    // ==>
    // t * (ax2 - ax1) * (by2 - by1) = (bx1 - ax1) * (by2 - by1) + u * (bx2 - bx1) * (by2 - by1)
    // t * (ay2 - ay1) * (bx2 - bx1) = (by1 - ay1) * (bx2 - bx1) + u * (by2 - by1) * (bx2 - bx1)
     System.out.printf(" t * %f = %f + u * %f\n", ax21*by21, bax1*by21, bx21*by21);
     System.out.printf(" t * %f = %f + u * %f\n", ay21*bx21, bay1*bx21, by21*bx21);
     System.out.printf(" ---\n");

    // ==>
    // t = (bx1 - ax1) * (by2 - by1) - (by1 - ay1) * (bx2 - bx1)
    //    / [ (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1)]
    // u = (ax1 - bx1) * (ay2 - ay1) - (ay1 - by1) * (ax2 - ax1)
    //    / [ (bx2 - bx1) * (ay2 - ay1) - (by2 - by1) * (ax2 - ax1)]
    nom = (bx1 - ax1) * (by2 - by1) - (by1 - ay1) * (bx2 - bx1);
    denom = (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1);
    double t = nom / denom;
     System.out.printf(" t = nom(%f) / denom(%f) = %f\n", nom, denom, t);

    nom = (ax1 - bx1) * (ay2 - ay1) - (ay1 - by1) * (ax2 - ax1);
    denom = (bx2 - bx1) * (ay2 - ay1) - (by2 - by1) * (ax2 - ax1);
    double u = nom / denom;
     System.out.printf(" u = nom(%f) / denom(%f) = %f\n", nom, denom, u);

    if(t>=0 && t <=1 && u>=0 && u<=1)  return true;
    else return false;
  }

  public static void main(String[] args)
  {
    if(args.length != 8)
    {
      System.out.println("java line 0 1 1 0 0 0 1 1");
      System.exit(0);
    }

    double ax1 = Double.parseDouble(args[0]);
    double ay1 = Double.parseDouble(args[1]);
    double ax2 = Double.parseDouble(args[2]);
    double ay2 = Double.parseDouble(args[3]);
    double bx1 = Double.parseDouble(args[4]);
    double by1 = Double.parseDouble(args[5]);
    double bx2 = Double.parseDouble(args[6]);
    double by2 = Double.parseDouble(args[7]);

    System.out.println(Line.isTwoLinesIntersecting(
      ax1,ay1,ax2,ay2,bx1,by1,bx2,by2));
  }
}

2009年7月10日 星期五

dictionary appendix to MMSEG


appendix to the mmseg Chinese word segmentation tool
http://sites.google.com/site/sekewei/home/download/dictionary.zip
---
readme.txt

filelist:
getdic.c source to retrieve dictionary in use
getdic.exe binary to retrieve dictionary in use
gcc -o getdic -I../src getdic.c ../src/lexicon.c

mmsegmnt.c source to segment a chunk in simple mode
getchunk.c source to get a chunk for segmenting
mmseg.exe binary to segment words
gcc -o mmseg -I. mmseg.c search.c
segment.c b5char.c iofiles.c
lexicon.c message.c
..\dictionary\getchunk.c
..\dictionary\mmsegmnt.c
mmseg inp.txt out.txt ../lexicon/ complex verbose
usage: mmseg in out lexicon [complex|simple*] [verbose|standard|quiet*]
default options are simple and quiet

mklex1.c source to build dictionary tables CHR?.TXT
mklex1.exe binary to build dictionary tables CHR?.TXT
gcc -o mklex1 -I. ..\dictionary\mklex1.c
mklex1 TSAIWORD.TXT

mklex2.c source to build dictionary tables CHR?.LEX
mklex2.exe binary to build dictionary tables CHR?.LEX
gcc -o mklex2 -I. ..\dictionary\mklex2.c
mklex2 .

mklex3.c source to build dictionary tables CHR?.INX
mklex3.exe binary to build dictionary tables CHR?.INX
gcc -o mklex3 -I. ..\dictionary\mklex3.c
mklex3 .

mmsegwords_raw.txt retrieved dictionary in use (137546 items)
mmsegwords.txt revised dictionary (137555 items)
mmsegwords_sort.txt revised dictionary sorted (137555 items)
TSAIWORD.TXT separate sorted dictionary by Tsai (137425 items)
diff.txt difference between mmsegwords_sort.txt
and TSAIWORD.TXT

2009年5月21日 星期四

interface finder


/*
 * @(#)InterfaceFinder.java v0.8, 2009/05/06-2020/2/8
 *
 *   Search the class path for classes which implement a specific interface
 *
 *   Usage: java -cp jar_file;class_folder;. InterfaceFinder interface_name_to_search
 */

import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.Stack;
import java.util.HashSet;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
  The interface finder is used to find all classes
  implementing a specific interface.
  The location in search includes all the subdirectories
  in the class path. Typical usage is as follows.

    List<Class> InterfaceFinder.getAvailableInterfaces("java.util.List");

 * @since 0.8
 * @version 0.8, 2009/05/06-2020/2/8
 * @author Seke Wei
*/
public class InterfaceFinder
{
  public static final String version="InterfaceFinder.java v0.8 2020/02/08";

  /**
    a file lister which uses the depth first strategy
    to traverse all files under a given directory.
  */
  public static class FileLister implements Enumeration
  {
    boolean hasMore;
    Stack<File> fstack;

    /**
      constructor for file lister.
      @param dir the root directory for search.
    */
    public FileLister(File dir)
    {
      fstack = new Stack<>();
      if(dir.isDirectory())
        fstack.push(dir);
      hasMore = true;
    }

    /**
      check if there is still file available for listing.
      @return true for elements available and false for otherwise.
    */
    public boolean hasMoreElements()
    {
      return hasMore;
    }

    /**
      get the next available file.
      directories are skipped.
      @return the file.
    */
    public File nextElement()
    {
      File next = null;

      while(fstack.empty()==false)
      {
        next = (File) fstack.pop();
        if(next.isFile())
          break;

        for(File f : next.listFiles())
          fstack.push(f);
      }

      if(fstack.empty()) hasMore=false;

      return next;
    }
  }

  /**
    get classes from a jar file which implements an interface.
    @param jarFileName the jar filename.
    @param iface the interface in search.
    @return the set of classes in jar implementing the interface.
  */
  public static List<Class> getClassesFromJARFile(String jarFileName, Class iface)
  {
    final List<Class> classes = new Vector<>();
    JarInputStream jarFile = null;
    String className = "";
    try
    {
      jarFile = new JarInputStream(new FileInputStream(jarFileName));
      JarEntry jarEntry;
      while(true)
      {
        jarEntry = jarFile.getNextJarEntry();
        if(jarEntry == null) break;

        className = jarEntry.toString();

        //System.err.println(className);

        if(className.endsWith(".class") && className.indexOf("$") < 0 )
        {
          //extractClassFromJar(jar, packageName, classes, jarEntry)
          className = className.replace('/','.');
          className = className.substring(0, className.length() - ".class".length());
          Class cl = Class.forName(className);
          if(iface.isAssignableFrom(cl))
          {
            //System.err.println("\t"+className+" can be assigned to "+iface);
            classes.add(cl);
          }
        }
      }
      jarFile.close();
    }
    catch (IOException ioe)
    {
      System.err.println("Unable to get Jar input stream from '"+jarFileName+"'"+ioe);
    }
    catch (ClassNotFoundException cnfe)
    {
      System.err.println("unable to find class named " + className.replace('/', '.') + "' within jar '" + jarFileName + "'"+cnfe);
    }

    return classes;
  }

  /**
    get classes from a root directory which implements an interface.
    @param dir the root directory.
    @param iface the interface in search.
    @return the set of classes in jar implementing the interface.
    @throws IOException when there is a file open error.
  */
  public static List<Class> getClassesFromDirectory(File dir, Class iface)
  {
    List<Class> classes = new Vector<>();

    FileLister lister = new FileLister(dir);
    while(lister.hasMoreElements())
    {
      File f = lister.nextElement();
      String className = f.toString();

      //System.err.println(className);

      if(className.endsWith(".class") && className.indexOf("$") < 0 )
      {
        className = className.replace(File.separatorChar,'.');
        className = className.substring(0, className.length() - ".class".length());
        while(className.charAt(0)=='.') className = className.substring(1);
        //System.err.println("\t"+className);

        try
        {
          Class cl = Class.forName(className);
          if(iface.isAssignableFrom(cl))
          {
            //System.err.println("\t"+className+" can be assigned to "+iface);
            classes.add(cl);
          }
        }
        catch(ClassNotFoundException cnfe)
        {}
      }
    }

    return classes;
  }

  /**
    get classes from the class path which implements an interface.
    @param iface the interface in search.
    @return the set of classes in jar implementing the interface.
  */
  public static List<Class> getAvailableClassesOfInterface(String iface)
  {
    List<Class> result = null;

    try
    {
      Class iface_class = Class.forName(iface);
      result = getAvailableClassesOfInterface(iface_class);
    }
    catch(ClassNotFoundException cnfe) {}

    return result;
  }

  /**
    get classes from the class path which implements an interface.
    @param iface the interface in search.
    @return the set of classes in jar implementing the interface.
  */
  public static List<Class> getAvailableClassesOfInterface(Class iface)
  {
    String cp = System.getProperty("java.class.path");
    //System.out.println("java.class.path = " + cp);

    List<Class> result = new Vector<>();

    // semicolon (Windows) or colon (Unix) by System.getProperty("path.separator")
    String separator = System.getProperty("path.separator");
    for(String p : cp.split(separator))
    {
      File f = new File(p);
      if(f.isDirectory())
        result.addAll(getClassesFromDirectory(f, iface));
      else if(f.isFile() && p.endsWith("jar"))
        result.addAll(getClassesFromJARFile(p, iface));
    }

    HashSet<Class> set = new HashSet<>(result);

    result.clear();

    for(Class c : set)
    {
      //System.err.println(c);
      result.add(c);
    }

    return result;
  }

  /**
     InterfaceFinder.java
 
        Search the class path for classes which implement a specific interface

     Usage: java -cp jar_file;class_folder;. InterfaceFinder interface_name_to_search

     Example:
     > javac InterfaceFinder.java
     > java -cp rt.jar;. InterfaceFinder java.util.List
     class javax.management.relation.RoleUnresolvedList
     class java.util.AbstractList
     class java.util.SubList
     class java.util.concurrent.CopyOnWriteArrayList
     class javax.management.AttributeList
     class java.util.AbstractSequentialList
     class java.util.RandomAccessSubList
     class java.util.ArrayList
     class java.util.Vector
     class java.util.Stack
     class java.util.LinkedList
     class javax.management.relation.RoleList
     interface java.util.List

     Note that since JDK 9 there is no rt.jar for testing
  */
  public static void main(String args[])
  {
    String iface = "java.util.List";
    if(args.length > 0)
      iface = args[0];

    List<Class> classes =
      getAvailableClassesOfInterface(iface);

    for(Class c : classes)
    {
      System.err.println(c);
    }
  }
}

2009年4月14日 星期二

computer speed of arithmetic operations


/**
根據speed.java四則運算時間測試結果,

整數乘/除餘運算時間約是整數加減運算時間的5/10倍以上
實數部份比較特別,乘和加減時間幾乎一樣,除法為加減法近200倍,求餘數為加減法近10倍以上.

C:\java>java speed ia is im id ip la ls lm ld lp fa fs fm fd fp da ds dm dd dp
The ia time is 438 ms, or 4.38000e-06 ms per ia
The is time is 422 ms, or 4.22000e-06 ms per is
The im time is 1906 ms, or 1.90600e-05 ms per im
The id time is 4938 ms, or 4.93800e-05 ms per id
The ip time is 5546 ms, or 5.54600e-05 ms per ip
The la time is 453 ms, or 4.53000e-06 ms per la
The ls time is 453 ms, or 4.53000e-06 ms per ls
The lm time is 2438 ms, or 2.43800e-05 ms per lm
The ld time is 7750 ms, or 7.75000e-05 ms per ld
The lp time is 7391 ms, or 7.39100e-05 ms per lp
The fa time is 328 ms, or 3.28000e-06 ms per fa
The fs time is 329 ms, or 3.29000e-06 ms per fs
The fm time is 328 ms, or 3.28000e-06 ms per fm
The fd time is 57422 ms, or 0.000574220 ms per fd
The fp time is 4860 ms, or 4.86000e-05 ms per fp
The da time is 328 ms, or 3.28000e-06 ms per da
The ds time is 328 ms, or 3.28000e-06 ms per ds
The dm time is 328 ms, or 3.28000e-06 ms per dm
The dd time is 66000 ms, or 0.000660000 ms per dd
The dp time is 4953 ms, or 4.95300e-05 ms per dp
*/
public class speed
{

public static long operation(String op, long loop)
{
int i=500, i2=100, i1=50;
long l=5000,l2=1000, l1=500;
float f=1e3f, f2=1.01f, f1=2e3f;
double d=1e6, d2=1.01, d1=2e2;
long k;

//int loop=(int) 1e6;
long start = System.currentTimeMillis();

if(op.equals("ia")) for(k=1; k<=loop; k++) i=i+i2;
else if(op.equals("is")) for(k=1; k<=loop; k++) i=i-i2;
else if(op.equals("im")) for(k=1; k<=loop; k++) i=i*i2;
else if(op.equals("id")) for(k=1; k<=loop; k++) i=i/i2;
else if(op.equals("ip")) for(k=1; k<=loop; k++) i=i%i2;

else if(op.equals("la")) for(k=1; k<=loop; k++) l=l+l2;
else if(op.equals("ls")) for(k=1; k<=loop; k++) l=l-l2;
else if(op.equals("lm")) for(k=1; k<=loop; k++) l=l*l2;
else if(op.equals("ld")) for(k=1; k<=loop; k++) l=l/l2;
else if(op.equals("lp")) for(k=1; k<=loop; k++) l=l%l2;

else if(op.equals("fa")) for(k=1; k<=loop; k++) f=f+f2;
else if(op.equals("fs")) for(k=1; k<=loop; k++) f=f-f2;
else if(op.equals("fm")) for(k=1; k<=loop; k++) f=f*f2;
else if(op.equals("fd")) for(k=1; k<=loop; k++) f=f/f2;
else if(op.equals("fp")) for(k=1; k<=loop; k++) f=f%f2;

else if(op.equals("da")) for(k=1; k<=loop; k++) d=d+d2;
else if(op.equals("ds")) for(k=1; k<=loop; k++) d=d-d2;
else if(op.equals("dm")) for(k=1; k<=loop; k++) d=d*d2;
else if(op.equals("dd")) for(k=1; k<=loop; k++) d=d/d2;
else if(op.equals("dp")) for(k=1; k<=loop; k++) d=d%d2;

long end = System.currentTimeMillis();
long time = end - start;

return time;
}

public static void main(String args[])
{
if(args.length==0)
{
System.err.println("java speed [i|l|f|d][a|s|m|d|p]");
System.exit(0);
}

for(int a=0; a < args.length; a++)
{
String op = args[a];

long loop = (long) 1e8;
long time = operation(op,loop);
System.err.printf("The %s time is %d ms, or %g ms per %s\n",
op, time, (float) time / loop, op);
}
}
}

2009年4月10日 星期五

scanner.next and nextLine

一般用掃瞄器物件(Scanner)時,若依下法,
在讀數字後,再讀文字,會有讀不到文字情況,


  Scanner sc = new Scanner(System.in);
  int i = sc.nextInt(); // 讀數字,換行字元未讀走
  String s = sc.nextLine(); // 讀換行前字串,會收到空字串


這時,建議改用如下寫法,


  Scanner sc = new Scanner(System.in);
  int i = sc.nextInt(); // 讀數字,換行字元未讀走
  String s = sc.nextLine(); // 故意用nextLine讀走下一換行前字串及換行字元
  String s = sc.nextLine(); // 再用nextLine重新讀下一換行前字串及換行字元

  Scanner sc = new Scanner(System.in);
  int i = sc.nextInt(); // 讀數字,換行字元未讀走
  String s = sc.next(); // 讀下一個空格隔開前文字,這樣非空格文字仍可讀到


如下測試範例 Test2.java 可自行試看看.

---- Test2.java -----------


/*
  Test2.java

  >javac Test2.java

  >java Test2
  input i=123
  input s=
  input s2=456
  i=123, s=, s2=456, end

*/
import java.util.*;

public class Test2
{
  public static void main(String[] arg)
  {
    Scanner sc = new Scanner(System.in);
    System.err.printf("input i=");
    int i = sc.nextInt();

    System.err.printf("input s=");
    String s = sc.nextLine();
    // 前面有讀數字,後面文字會讀不到,只收到空字串

    System.err.printf("\ninput s2=");
    String s2 = sc.nextLine();

    System.err.printf("i=%d, s=%s, s2=%s, end\n",i,s, s2);
  }
}

2009年4月8日 星期三

summary of time complexity for common data structures


常見資料結構之平均時間複雜度
=======================

運算之平均時間複雜度 新增 刪除 查詢
--限特定位置增刪查詢之線性容器--
陣列堆疊(尾入尾出) O(1) O(1) O(1)
鏈結堆疊(頭入頭出) O(1) O(1) O(1)
陣列佇列(環狀尾入頭出) O(1) O(1) O(1)
鏈結佇列(尾入頭出) O(1) O(1) O(1)
陣列雙邊佇列(環狀頭尾出入) O(1) O(1) O(1)
鏈結雙邊佇列(雙向頭尾出入) O(1) O(1) O(1)

--線性容器--
無序陣列清單 O(1) O(n) O(n)
無序鏈結清單 O(1) O(n) O(n)
有序陣列清單 O(n) O(n) O(log(n))
有序鏈結清單 O(n) O(n) O(n)
雜湊表 O(1) O(1) O(1)

--非線性容器--
二分搜索樹 O(log(n)) O(log(n)) O(log(n))
跳躍鏈結清單 O(log(n)) O(log(n)) O(log(n))
堆積(限頭才能刪除,查詢) O(log(n)) O(log(n)) O(1)

參考:
1.carrano-pie-05-data abstraction & problem solving with java
2.weiss-pie-04-data structures & problem solving using java
3.budd-awl-00-classic data structures in java

java container (jdk1.5)

java容器(since jdk1.5版)   Version 0.2b, 2006/10/26
==================

各容器介面摘要(功能定義):
  Collection 收藏:    放個別物件,  可重複放,無位置概念,無排序
  Queue 佇列:         放個別物件,  可重複放,頭位置概念,部份排序
  List 清單:          放個別物件,  可重複放,任意位置  ,無排序
  Set 集合:           放個別物件,不可重複放,無位置概念,無排序
  SortedSet 有序集合: 放個別物件,不可重複放,有頭尾概念,有排序
  Map 映射:           放成對物件,不可重複放,無位置概念,無排序
  SortedMap 有序映射: 放成對物件,不可重複放,有頭尾概念,有排序

各容器類別摘要(實作各介面的實體類別):
  Collection:   Vector,Stack,ArrayList,ArrayBlockingQueue,
  LinkedList,PriorityQueue,HashSet,TreeSet
  Queue: ArrayBlockingQueue,LinkedList,PriorityQueue
  List:  Vector,Stack,ArrayList,LinkedList
  Set:  HashSet,TreeSet
  SortedSet: TreeSet
  Map:  HashMap,TreeMap,HashTable,Properties
  SortedMap: TreeMap
  --
  Vector 向量,Stack 堆疊,ArrayList 陣列清單,LinkedList 鏈結清單,
  ArrayBlockingQueue 陣列等候佇列,PriorityQueue 順位佇列,
  HashSet 雜湊集合,TreeSet 樹狀集合,
  HashMap 雜湊映射,TreeMap 樹狀映射,
  HashTable 雜湊表,Properties 屬性表

容器演算法:
  Collections.binarySearch/min/max/indexOfSublist/lastIndexOfSublist,
 fill/copy/swap/shuffle/sort/reverse/rotate,
 list/nCopies/enumeration/reverseOrder,
 singleton/singletonList/singletonMap,
 synchronizedCollection/synchronizedSet/synchronizedList,
 synchronizedMap/synchronizedSortedSet/synchronizedSortedMap,
 unmodifiableCollection/unmodifiableSet/unmodifiableList,
 unmodifiableMap/unmodifiableSortedSet/unmodifiableSortedMap,

  Arrays.asList/binarySearch/equals/fill/sort,

容器一般性功能須求:
 新增容器,刪除容器,查詢容器元素個數,列舉容器元素,
 新增元素,刪除元素,修改元素,查詢元素,擷取元素

各容器類別提供的方法:

 Vector >AbstractList >AbstractCollection, 存取有同步,有元素概念,容量無限
 *add/addElement/insertElementAt/addAll,
 *remove/removeElement/removeElementAt,
 clear/removeAllElements/removeAll/retainAll/removeRange,
 *get/set/firstElement/lastElement/elementAt/setElementAt,
 *indexOf/lastIndexOf,
 subList/toArray/copyInto,
 isEmpty/contains/containsAll/equals/hasCode,
 *size/setSize/trimToSize/capacity/ensureCapacity,
 toString/clone,
 --
 iterator/listIterartor

 Stack >Vector >AbstractList >AbstractCollection, 存取有同步
 *empty/push/peek/pop/search,
 --
 add/addElement/insertElementAt/addAll,
 remove/removeElement/removeElementAt,
 clear/removeAllElements/removeAll/retainAll/removeRange,
 get/set/firstElement/lastElement/elementAt/setElementAt,
 indexOf/lastIndexOf,
 subList/toArray/copyInto,
 isEmpty/equals/contains/containsAll/hasCode,
 size/setSize/trimToSize/capacity/ensureCapacity,
 toString/clone,
 --
 iterator/listIterartor

 ArrayList >AbstractList >AbstractCollection, 存取無同步,容量無限
 *add/addAll,
 *remove/removeRange/clear,
 *get/set,
 *indexOf/lastIndexOf,
 *isEmpty/contains,
 size/trimToSize/ensureCapacity,
 clone/toArray,
 --
 iterator/listIterartor/equals/hasCode,
 --
 containsAll/removeAll/retainAll/toString

 ArrayBlockingQueue >AbstractQueue >AbstractCollection 存取有同步,容量有限制
 clear/contains/drainTo/iterator/
 offer/peek/poll/put/remove/take
 remainingCapacity/size/
 toArray/toString
 --
 add/addAll/element/remove
 --
 containsAll/isEmpty/removeAll/retainAll

 PriorityQueue >AbstractQueue >AbstractCollection 存取無同步,容量無限
 add/clear/offer/peek/poll/remove
 comparator/iterator/size
 --
 addAll/element/remove
 --
 contains/containsAll/isEmpty/removeAll/retainAll
 toArray/toString

 LinkedList >AbstractSequentialList >AbstractList
     >AbstractCollection, 存取無同步,有頭尾概念,容量無限
 *add/addAll/addFirst/addLast,
 *remove/removeFirst/removeLast/clear,
 *get/set/getFirst/getLast,
 *contains/indexOf/lastIndexOf,
 size/listIterator/clone/toArray,
 --
 iterator
 --
 equals/hashCode/removeRange/subList
 containsAll/isEmpty/removeAll/retainAll/toString

 HashSet >AbstractSet >AbstractCollection, 存取無同步,無順序概念
 *add/remove/clear,
 *contains/isEmpty/size,
 *iterator/clone,
 --
 equals/hashCode/removeAll
 --
 addAll/containsAll/retainAll/toArray/toString

 TreeSet >AbstractSet >AbstractCollection, 存取無同步,有順序概念
 *add/addAll/remove/clear,
 *contains/isEmpty/size,
 *iterator/clone/comparator,
 *first/last,
 *headSet/tailSet/subSet,
 --
 equals/hashCode/removeAll
 --
 containsAll/retainAll/toArray/toString

 HashMap >AbstractMap, 存取無同步,存放成對物件,無順序概念
 *get/put/putAll/remove/clear,
 *isEmpty/containsKey/containsValue,
 values/keySet/entrySet,
 size/clone
 --
 equals/hashCode/toString

 TreeMap >AbstractMap, 存取無同步,存放成對物件,有順序概念
 *get/put/putAll/remove/clear,
 *containsKey/containsValue,
 *headMap,tailMap,subMap,
 values/keySet/entrySet,
 firstKey/lastKey,
 size/clone/comparator,
 --
 equals/hashCode/isEmpty/toString

 HashTable >Dictionaries, 存取有同步,存放成對鍵值組
 *get/put/putAll/remove/clear,
 *isEmpty/containsKey/containsValue/contains,
 keys/elements/values/keySet/entrySet,
 size/clone/equals/hasCode/rehash/toString
 --
 get/put/remove,
 elements/keys,
 size/isEmpty,

 Properties >HashTable >Dictionaries, 存取有同步,存放屬性鍵值組
 *getProperty/setProperty,
 *load/store/list,
 *propertyNames,
 --
 *get/put/putAll/remove/clear,
 *isEmpty/containsKey/containsValue/contains,
 keys/elements/values/keySet/entrySet,
 size/clone/equals/hasCode/rehash/toString



各容器介面提供的方法:

 Collection
 add/allAll/remove/removeAll/retainAll/clear,
 isEmpty/contains/containsAll/equals/hasCode/size,
 iterator/toArray,

 Queue >Collection 多了頭位置概念
 offer/
 poll/remove/
 peek/element/
 --
 add/allAll/remove/removeAll/retainAll/clear,
 isEmpty/contains/containsAll/equals/hasCode/size,
 iterator/toArray,

 List >Collection 多了任意位置概念
 add/allAll/remove,
 get/set,
 indexOf/lastIndexOf,
 listIterator/subList,
 --
 add/allAll/remove/removeAll/retainAll/clear,
 isEmpty/contains/containsAll/equals/hasCode/size,
 iterator/toArray,

 Set >Collection 多了不重複存放概念
 add/allAll/remove/removeAll/retainAll/clear,
 isEmpty/contains/containsAll/equals/hasCode/size,
 iterator/toArray,

 SortedSet >Set >Collection 多了順序概念
 first/last,
 headSet/tailSet/subSet,
 comparator,
 --
 add/allAll/remove/removeAll/retainAll/clear,
 isEmpty/contains/containsAll/equals/hasCode/size,
 iterator/toArray,

 Map
 get/put/putAll/remove/clear,
 isEmpty/containsKey/containsValue,
 values/keySet/entrySet,
 size/equals/hasCode,

 SortedMap >Map
 firstKey/lastKey,
 headMap/tailMap/subMap,
 comparator,
 --
 get/put/putAll/remove/clear,
 isEmpty/containsKey/containsValue,
 values/keySet/entrySet,
 size/equals/hasCode,



迭代列舉介面提供的方法:

 Enumeration 列舉介面,不能刪除列舉物件,只能往後列舉
 hasMoreElements/nextElement,

 Iterator 迭代介面,可刪除列舉物件,只能往後列舉
 hasNext/next/remove,

 ListIterator 清單迭代介面,可往前後列舉,及增刪改物件
 add/set/remove,
 hasNext/hasPrevious,
 next/previous,
 nextIndex,previousIndex,

可比較及比較器介面提供的方法:
java.lang.Comparable 可比較介面
 compareTo

java.util.Comparator 比較器介面
 compare/equals

2009年3月19日 星期四

method and call stack

程式呼叫方法(method)步驟:
1.進入方法前,先壓入返回位址(return address)到堆疊(call stack)
2.進入方法後,利用堆疊配置區域變數(local variable)空間
3.依序拷貝引數列(argument list)數值到參數列(parameter list)變數
4.開始執行方法內指令,直到遇到return指令或方法結束大括號}
5.離開方法前,釋放堆疊的區域變數空間
6.從堆疊彈出返回位址,從返回位址繼續執行指令

2009年2月9日 星期一

methods for creating a self-contained .jar with data file


Given Main.java, data1.dat, data2.dat,
methods for creating a self-contained .jar with data file
0.use getResourceAsStream to get jar data at package root
InputStream is = Main.class.getResourceAsStream("/"+dataName);

1.add to all *.java source
package my.package;

2.compile with package start location
java -d . *.java

3.vi manifest.txt
#Class-Path: my.package
Main-Class: my.package.Main

4.produce jar file with data files
jar cvfm mypackage.jar manifest.txt my data1.dat data2.dat

5.run by
java -jar mypackage.jar
java -cp mypackage.jar my.package.Main