<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks

    #

    一直以來,整合Apache HTTP Server和其他Java容器時,可能你最好的選擇就是mod_jk,但是mod_jk在Apache和外部Java服務器之間使用socket來進行協議轉換,性能不能盡如人意。
    正如我上一篇博客里說的,mod_java通過在apache嵌入的JVM中直接執行Java來響應HTTP請求,當然是要快于mod_jk的。

    但是缺點是,不是Servlet API(雖然實現Servlet API不是很難,但是工作量肯定很大的),優點是,接口很清晰,很靈活,可以做到的事情也就很多。


    那么如何開發一個基于mod_java的java handler呢?OK,假設你要在Apache里響應所有/test/*上的請求.
    你要做的是:
    1)配置Apache啟用mod_java
    LoadModule java_module modules/mod_java.so

    <mod_java your_main_class>
    JVMLibrary D:\jdk6\jre\bin\server\jvm.dll
    CurDir D:\apache-tomcat-6.0.14
    ADDJVMOpt -Djava.class.path=D:\apache-tomcat-6.0.14\bin\bootstrap.jar;D:\dev\vccode\mod_java\mod_java.jar
    ADDJVMOpt -Djava.library.path=D:\apache-tomcat-6.0.14\bin
    ADDJVMOpt -Dcatalina.home=D:\apache-tomcat-6.0.14
    ADDJVMOpt -Duser.dir=D:\apache-tomcat-6.0.14
    ADDJVMParam start
    ADDJVMStopParam stop
    ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
    </mod_java>
    這里main_class是可選的,如果有,那么JVM啟動時自動調用main方法。

    2)在配置文件里加入你將要開發的Java Handler
    想上面文件中的
    ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
    這里 javatest是handler名字,后面是你的實現的class
    3)在配置文件里告訴Apache 你的handler名字對應的路徑
    <Location /test>
        SetHandler javatest
    </Location>

    完成這些配置動作后,apache在收到到/test/*的請求后mod_java會call你的handler class的processRequest方法了。

    RequestHandler接口如下定義,你的Handler都需要實現該接口:
    package com.yovn.apache.modj;

    import java.io.IOException;

    /**
     * 
    @author yovn
     * 
     
    */
    public  interface RequestHandler {

        
    public abstract void processRequest(ModJRequest request) throws IOException,
                ModJavaException;

    }

    正如你看到的很簡單的接口,但是ModJRequest就不簡單了,該接口代表你跟Apache通行的直接的接口,目前定義如下:

    package com.yovn.apache.modj;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.ByteBuffer;

    /**
     * 
    @author yovn
     *
     
    */
    public interface ModJRequest {
        
        
    /**
         * 
         * 
    @param name
         * 
    @return the request header value of that name
         
    */
        String getRequestHeader(String name);
        
        
    /**
         * 
         * 
    @return similar as HttpServletRequest.getRequestURI()
         
    */
        String getRequestURI();
        
    /**
         * 
         * 
    @param name header name
         * 
    @param value header value
         
    */
        
    void setResponseHeader(String name,String value);
        
        
    /**
         * 
         * 
    @param type 'text/html' etc.. 
         
    */
        
    void setContentType(String type);
        
        
    /**
         * 
         * 
    @param code response code
         
    */
        
    void setResponseCode(int code);
        
        
    /**
         * 
         * 
    @return HTTP method
         
    */
        String getMethod();
        
        
        
    /**
         * Give you the  chance when you need push datas to client
         * Also,you can use it to close a connection 
         * Note:
         * HTTP Server may close the connection when it timeout automatically.
         * When you pass use an invalid connection id to call some function , it will failed.
         * 
    @see com.yovn.apache.modj.ApacheModule#flushConnection(long, byte[], int, int)
         * 
    @see com.yovn.apache.modj.ApacheModule#closeConnection(long)
         * 
    @return the connection id for this request.
         
    */
        
    long getConnectionId();
        
        
    /**
         * same as HttpServletRequest.getServletInputStream
         * 
    @return 
         
    */
        InputStream getRequestInputStream();
        
        
    /**
         * same as HttpServletResponse.getServletOutputStream
         * 
    @return
         
    */
        OutputStream getResponseOutputStream();
        
        
        
    /**
         * You should not call the {
    @link #getRequestInputStream()} before you call this method this method.
         * In other words, You should either use this method or {
    @link #getRequestInputStream()}  to do read data from clients
         * 
    @return the direct byte buffer from native side
         * 
    @throws IOException
         
    */
        ByteBuffer readTotalRequestBody()
    throws IOException;
        
        
        
    /**
         * Use apache's apr_send_fd to send a file.
         * Before send file, you may need setup proper HTTP headers, such as 'Content-Disposition' 
         * 
    @param fileName
         * 
    @return 
         * 
    @throws IOException
         
    */
        
    boolean sendFile(String fileName)throws IOException;

    }
    如你所看,基本可以做任何事情(如果還有你想要而沒有請一定要告訴我哦)!

    下面給個發送文件的例子:

    /**
     * 
     
    */
    package com.yovn.apache.modj;

    import java.io.File;
    import java.io.IOException;

    /**
     * 
    @author yovn
     *
     
    */
    public class HelloWorld implements RequestHandler {

        
    /**
         * 
         
    */
        
    public HelloWorld() {
            
    // TODO Auto-generated constructor stub
        }

        
    /*
         * (non-Javadoc)
         * 
         * @see com.yovn.apache.modj.RequestHandler#processRequest(ModJRequest request)
         
    */

        
    public void processRequest(ModJRequest request) throws IOException,
                ModJavaException {

            request.setContentType(
    "APPLICATION/OCTET-STREAM");
        

            File f
    =new File("D:\\cspace\\mod_java\\release\\ddd.bin");
            request.setResponseHeader(
    "Content-Disposition""attachment;filename=\"ddd.bin\"");
            request.setResponseHeader(
    "Content-Length",f.length()+"");
            
            request.sendFile(f.getCanonicalPath());
            

        }

    }

    下載:
    mod_java_0.1

    posted @ 2008-06-19 15:38 DoubleH 閱讀(4710) | 評論 (5)編輯 收藏

    一 。Apache Java Module是什么?

    Apache Java Module是一個Apache2.2 Server下的一個模塊,這個模塊可以嵌入一個JVM,可以無縫地跟Apache整合在一塊,從而便于發布高性能的基于Java的HTTP解決方案。

    二。為什么要這么做
    1)首先,Apache是HTTP服務器市場的領頭羊
    2)處于性能的考量。
    3)Servlet API有它本身的局限性,例如連接相關的信息基本是被隱藏起來了,這樣當你想要異步推數據給客戶端時,只能去求助Comet了。
    4)只要愿意,我可以同時跑Apache和Tomcat,并在一個進程內同時為兩個端口服務。
    三。示例

    目前初步實現了基本框架,一個Hellow,world的例子見下:
    首先配置Apache,在conf文件里加上:
    LoadModule java_module modules/mod_java.so

    <mod_java org.apache.catalina.startup.Bootstrap>
    JVMLibrary D:\jdk1
    .6\jre\bin\server\jvm.dll
    CurDir D:\apache-tomcat-
    6.0.10
    ADDJVMOpt -Djava.class.path
    =D:\apache-tomcat-6.0.10\bin\bootstrap.jar;D:\cspace\mod_java\mod_java.jar
    ADDJVMOpt -Djava.library.path=D:\apache-tomcat-6.0.10\bin
    ADDJVMOpt -Dcatalina.home
    =D:\apache-tomcat-6.0.10
    ADDJVMOpt -Duser.dir
    =D:\apache-tomcat-6.0.10
    ADDJVMParam start
    ADDJVMStopParam stop
    ADDJavaHandler javatest com.yovn.apache.modj.HelloWorld
    </mod_java>
    <Location /javatest>
        SetHandler javatest
    </Location>

    這段配置腳本,同時會啟動一個Tomcat在一個新的線程。
    并且,當你請求/javatest/*時,自動會執行com.yovn.apache.modj.HelloWorld來滿足這個請求,下面看
    這個示例程序:

    /**
     * 
     
    */
    package com.yovn.apache.modj;

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintStream;

    /**
     * 
    @author yovn
     *
     
    */
    public class HelloWorld implements RequestHandler {

        
    /**
         * 
         
    */
        
    public HelloWorld() {
            
    // TODO Auto-generated constructor stub
        }

        
    /* (non-Javadoc)
         * @see com.yovn.apache.modj.RequestHandler#processRequest(java.lang.String, int, long, long, java.io.InputStream, java.io.OutputStream)
         
    */
        @Override
        
    public void processRequest(String url, int method, long req, long conn,
                InputStream in, OutputStream out) 
    throws IOException,
                ModJavaException {
        

            //ApacheModule.setHeader(req, "X-Server", "mod_java");
            out.write("<html><head><title>Hello,World</title></head><body><h1>Hello,World</h1></body></html>".getBytes());
            out.close();

            

        }

    }
    這是個很簡單的程序,當你在瀏覽器輸入http://host:apache_port/javatest/時,顯示Hello,World.

    目前讀取輸入數據尚未實現,等完善了我再提供下載文件。


    posted @ 2008-06-18 00:05 DoubleH 閱讀(2076) | 評論 (1)編輯 收藏

    問題背景
    面對艱巨復雜的技術挑戰,百度所崇尚的系統設計哲學是“簡單可依賴”,而百度的工程師們正在互聯網世界中實踐著這種理念。這里正好有一個挑戰,讓作為百度之星的你小試牛刀:

    在處理數以百億計的網絡信息的過程中,有一個很常見的問題: 
    怎么樣將一個集群上的信息以最低的成本傳輸到另外一個集群上?


    數據源集群A有n臺服務器,編號為 1, 2, ..., n,i號服務器上待傳輸的數據量為Ai ,單位是GB。 
    目的地集群B有m臺服務器,編號為 1, 2, ..., m,j號服務器上的空閑容量為 Bj,單位為 GB。 
    A集群的i號服務器上的每GB數據對于B的集群的j號服務器收益為Vi,j,從 A 集群的 i 號服務器向 B 集群的 j 號服務器傳輸 1GB數據的開銷為Ci,j。 
    你的任務是在保證A中的所有數據傳輸完畢的前提下,性價比V/C盡量高。其中V為所有數據在B集群上的價值之和,C為總開銷。換句話說,若A集群的i號服務器向B集群的j號服務器發送了Ti,j個GB的數據(Ti,j不一定是整數),則性價比定義為:





    輸入格式
    第1行兩個整數n, m(1<=n,m<=50),即集群A和B各自的服務器臺數。
    第2行包含n個不超過100的正整數A1,A2,…,An,即集群A中每臺服務器的待傳輸數據量(單位:GB)。
    第3行包含m個不超過100的正整數B1,B2,…,Bm,即集群B中每臺服務器所能接受的最大數據量(單位:GB)。
    第 4 ~ n+3 行每行包含m個不超過100的非負整數Vi,j,表示集群A的i號服務器中每GB數據對于集群B中的j號服務器的價值。
    第 n+4 ~ 2n+3 行每行包含m個不超過100的正整數Ci,j,表示集群A的i號服務器中每GB數據傳輸到集群B中的j號服務器所需要的開銷。 

    輸出格式
    僅一行,為最大性價比。輸出保留三位小數(四舍五入)。如果A的數據無法傳輸完畢,輸出字符串 “-1”(無引號)。 

    樣例輸入
    2 2
    1 2
    2 1
    11 0
    7 5
    6 1
    3 2 

    樣例輸出
    2.091 

    樣例解釋
    一個方案是:
    集群A的1號服務器把所有數據傳輸到集群B的1號服務器,價值11,開銷6。
    集群A的2號服務器把1GB數據傳輸到集群B的1號服務器,價值7,開銷3,然后把剩下的1GB數據傳輸到集群B的2號服務器,價值5,開銷2。
    性價比:(11+7+5)/(6+3+2)=2.091

    另一個方案是:
    集群A的1號服務器把所有數據傳輸到集群B的2號服務器,價值0,開銷1。
    集群A的2號服務器把所有數據傳輸到集群B的1號服務器,價值14,開銷6。
    性價比:(0+14)/(1+6)=2。

    第一種方案更優

    我的解答:
    該題應該是貪心法可解,每次求性價比最高的,跟部分背包問題很像。
    可惜不是,子問題不是獨立的,我的解法肯定不是最優解。sign~~~,據說是最大流的問題,改天研究研究。
    我的解法用了N+1個最大值堆,一個是全局所有為傳輸完的源站點的最高性價比方案,
    其余每個源站點一個最大值堆含該站點所有傳輸方案。

    //============================================================================
    // Name        : TransportOpt.cpp
    // Author      : Yovn
    // Version     :
    // Copyright   : yovnchine@gmail.com
    //============================================================================

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdio>

    using namespace std;



    int numA;
    int numB;
    int* valuesA;
    int* valuesB;
    int** values=NULL;
    int** costs=NULL;


    typedef struct _HeapNode
    {
        int a;
        int b;
        float vPerC;
       
    }HeapNode;
    class MaxHeap
    {
    public:
        MaxHeap(int n):nodes(new HeapNode[n]),total(n),len(0){
           
        }
        MaxHeap():nodes(NULL),total(0),len(0){
               
        }
        ~MaxHeap()
        {
            delete[] nodes;
        }
        bool isEmpty()
        {
            return len<=0;
        }
        void setSize(int n)
        {
            nodes=new HeapNode[n];
            total=n;
            len=0;
        }
        HeapNode removeMax()
        {
           
            HeapNode ret=nodes[0];
            nodes[0]=nodes[--len];
            shift_down(0);
            return ret;
        }
        void insert(HeapNode val)
        {
           
            nodes[len++]=val;
            shift_up(len-1);
        }
       
    private :
       
       
        void shift_up(int pos) {

            HeapNode tmp=nodes[pos];
            int index=(pos-1)/2;
       
            while (index>=0) {
                if (tmp.vPerC>nodes[index].vPerC) {
                    nodes[pos]=nodes[index];
                    pos=index;
                    if (pos==0)
                        break;
                    index=(pos-1)/2;
                } else
                    break;
            }
            nodes[pos]=tmp;
        }
        void shift_down(int pos) {

            HeapNode tmp=nodes[pos];
            int index=pos*2+1;//use left child
            while (index<len)//until no child
            {
                if (index+1<len&&nodes[index+1].vPerC>nodes[index].vPerC)//right child is smaller
                {
                    index+=1;//switch to right child
                }
                if (tmp.vPerC<nodes[index].vPerC) {
                    nodes[pos]=nodes[index];
                    pos=index;
                    index=pos*2+1;

                } else {
                    break;
                }

            }
            nodes[pos]=tmp;
           
        }
        HeapNode* nodes;
        int total;
        int len;


       
    };

    void parseToInts(string& line, int* arr, int num) {
        int pos=0;
        for (int i=0; i<line.length(); i++) {
            if (line[i]>='0'&&line[i]<='9') {
                if (line[i+1]>='0'&&line[i+1]<='9') {
                    int a=(line[i]-'0')*10+(line[i+1]-'0');
                    arr[pos++]=a;
                    i++;
                } else {
                    int a=(line[i]-'0');
                    arr[pos++]=a;
                   
                }
               
            }
        }
    }
    void input()
    {
        string line;
        getline(cin,line);
       
        sscanf(line.c_str(),"%d %d",&numA,&numB);
        valuesA=new int[numA];
        valuesB=new int[numB];
        line.clear();
        getline(cin,line);
        parseToInts(line,valuesA,numA);
       
        line.clear();
        getline(cin,line);
        parseToInts(line,valuesB,numB);
       
      
        values=new int*[numA];
        costs=new int*[numA];
        for (int i=0; i<numA; i++) {
            values[i]=new int[numB];
            line.clear();
            getline(cin, line);
            parseToInts(line, values[i], numB);
        }
       
        for (int i=0; i<numA; i++) {
            costs[i]=new int[numB];
            line.clear();
            getline(cin, line);
            parseToInts(line, costs[i], numB);
        }
       
       
       
    }
    bool validate() {
        int sumA=0, sumB=0;
        for (int i=0; i<numA; i++) {
            sumA+=valuesA[i];
        }
        for (int i=0; i<numB; i++) {
            sumB+=valuesB[i];
        }
        return sumA<=sumB;
    }
    void calc() {
        MaxHeap totalHeap(numA);
        MaxHeap* aHeaps=new MaxHeap[numA];
        int totalC=0;
        int totalV=0;

        if(!validate())
        {
            printf("-1\n");
            return;
        }
        for (int i=0; i<numA; i++) {

            aHeaps[i].setSize(numB);
            for(int j=0;j<numB;j++)
            {
                HeapNode node;
                node.a=i;
                node.b=j;
                node.vPerC=(float)values[i][j]/(float)costs[i][j];
                aHeaps[i].insert(node);
            }
            totalHeap.insert(aHeaps[i].removeMax());
        }
        while(!totalHeap.isEmpty())
        {
            HeapNode node=totalHeap.removeMax();
       
            if(valuesA[node.a]==valuesB[node.b])
            {
                totalV+=values[node.a][node.b]*valuesA[node.a];
                totalC+=costs[node.a][node.b]*valuesA[node.a];
                valuesB[node.b]=0;
                valuesA[node.a]=0;
               
            }
            else if(valuesA[node.a]>valuesB[node.b])
            {
                totalV+=values[node.a][node.b]*valuesB[node.b];
                totalC+=costs[node.a][node.b]*valuesB[node.b];
                valuesA[node.a]-=valuesB[node.b];
                valuesB[node.b]=0;
               
            }
            else
            {
                totalV+=values[node.a][node.b]*valuesA[node.a];
                totalC+=costs[node.a][node.b]*valuesA[node.a];
                valuesB[node.b]-=valuesA[node.a];
               
                valuesA[node.a]=0;
           
            }
            while(!aHeaps[node.a].isEmpty())
            {
                HeapNode todo=aHeaps[node.a].removeMax();
                if(valuesA[todo.a]>0&&valuesB[todo.b]>0)
                {
                    totalHeap.insert(todo);
                    break;
                }
            }
        }
        printf("%lf\n",(float)totalV/totalC);
    }
    int main() {
       
        input();
        calc();
       
        return 0;
    }




    posted @ 2008-06-01 18:53 DoubleH 閱讀(2443) | 評論 (0)編輯 收藏

    問題背景

    有一種簡單的網頁判重的方法,通過求兩個網頁內容的最長公共子序列(LCS)長度來判定兩個網頁的相似程度。如:
    (網頁A)老師:請用“果然”造句。
    (網頁B)學生:先吃水果,然后喝汽水……
    它們的最長公共子序列為“果然”,長度為2。注意這里的“子序列”并不要求連續。

    類似的,下面兩個網頁:
    (網頁A)老師:請用“果然”造句。
    (網頁B)學生:先吃水果,然后喝汽水,果然拉肚子……

    最長公共子序列還是“果然”,長度為2。但不難看出,由于“果然”兩個字在網頁B中也曾連續出現,第二組網頁比第一組更加“相似”。為了區分開這兩種情況的區分度,我們改用一種稱為LZW的理論。為了嚴格的敘述相似度的計算方法,我們首先定義“文本單元”。

    假定網頁用一個不包含空白字符(空格、回車換行、水平制表符)的字符串來表示。它只包含純文本,沒有標簽。在計算相似度之前,你應該首先對該字符串進行處理,劃分成一個個“文本單元”。每個文本單位可以是一個中文字、英文單詞(由一個或多個連續的半角英文字母和數字組成,正規表達式為[a-zA-Z0- 9]+)、或者一個標點符號。

    根據上述定義,同一個標點符號的全角和半角應該被作為不同的文本單元,盡管他們看起來可能很相近;每個單獨全角英文和全角數字都應該被看成一個單獨的文本單元,而連續的半角英文字母和數字應被看成一個整體。總之,全角的字符可以與中文字同等對待。

    這樣,網頁被看成文本單元序列。例如,網頁“內容?123456??web2.00#”切分出的文本單元序列為(為了顯示方便,用下劃線分隔各文本單元):
    內_容_?_1_2_345_6_?_?_web2_._00_#

    而網頁“why內容相似??1234567890,web#00”的切分結果為:
    why_內_容_相_似_?_?_1234567890_,_web_#_00

    黑體部分給出了兩個網頁的一個公共子序列。注意“內容”、“??”分別在兩個網頁中都是連續出現的文本單元。為了獎勵這種情況,LZW規定一段由連續k個文本單元組成的字符串權值為k^2。在剛才的例子中,“內容”、“??”的權值均為4。但“00”是一個數字串,應當被看成一個單獨的文本單元。所以權值僅為1。

    根據上述規則,公共子序列“內容 ?? 00”的權值為2^2+2^2+1=9。在所有可能的子序列中,這個權值是最大的。

    給定兩個網頁,求他們的LZW相似度,即所有可能的公共子序列中的最大權值。

    注意

    1) 輸入的網頁內容以GBK編碼(參見FAQ)
    2) 除了大小寫英文字母和數字之外的其他半角字符均視為標點符號。
    輸入格式

    包含兩行,分別是網頁A和B對應的字符串(不包含空白字符)。每行至少包含5個字節,最多包含200個字節。
    輸出格式

    輸出僅一行,包含一個整數,為兩個網頁的LZW相似度。
    樣例輸入

    內容?123456??web2.00#
    why內容相似??1234567890,web#00
    樣例輸出
    9


    解答:
    該題主要分兩部分,一部分就是解析成文本單元,另一部分就是LZW的實現,LZW其實是最長公共子序列算法的一個變形。

    //============================================================================
    // Name        : LZW.cpp
    // Author      : Yovn
    // Version     :
    // Copyright   : yovnchine@gmail.com
    //============================================================================

    #include 
    <iostream>
    #include 
    <string>
    #include 
    <cstring>
    using namespace std;

    void parseToLZWLine(const char* in, int inLen, char**& out, int& actualLen) {
        
    int mark=0;
        actualLen
    =0;
        out
    =new char*[inLen];

        
    for (int i=0; i<inLen; i++) {
            
    char ch=in[i];
            
    if (ch<0) {
                
    if (mark<i) {
                    out[actualLen]
    =new char[i-mark+1];
                    strncpy(out[actualLen], in
    +mark, i-mark);
                    out[actualLen][i
    -mark]='\0';
                    actualLen
    ++;
                }
                out[actualLen]
    =new char[3];
                out[actualLen][
    0]=ch;
                out[actualLen][
    1]=in[++i];
                out[actualLen][
    2]='\0';
                actualLen
    ++;

                mark
    =i+1;
            } 
    else if ((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')) {
                
    continue;
            } 
    else//only one case left
            {
                
    if (mark<i) {
                    out[actualLen]
    =new char[i-mark+1];
                    strncpy(out[actualLen], in
    +mark, i-mark);
                    out[actualLen][i
    -mark]='\0';
                    actualLen
    ++;

                }
                out[actualLen]
    =new char[2];
                out[actualLen][
    0]=ch;
                out[actualLen][
    1]='\0';
                actualLen
    ++;
                mark
    =i+1;
            }
        }
        
    if (mark<inLen) {
            out[actualLen]
    =new char[inLen-mark+1];
            strncpy(out[actualLen], in
    +mark, inLen-mark);
            out[actualLen][inLen
    -mark]='\0';
            actualLen
    ++;

        }
    }
    void printLZWStr(char** lzwStr, int lzwLen) {
        
    for (int i=0; i<lzwLen; i++) {
            printf(
    "%s", lzwStr[i]);
            
    if (i<lzwLen-1) {
                printf(
    "_");
            }
        }
        printf(
    "\n");
    }
    void freeLZWStr(char** lzwStr, int lzwLen) {
        
    for (int i=0; i<lzwLen; i++) {
            delete[] lzwStr[i];
        }
        delete[] lzwStr;
    }

    int calcLZW(char** left, int leftLen, char** right, int rightLen) {
        
    //printLZWStr(left, leftLen);
        
    //printLZWStr(right, rightLen);
        int** result=new int*[leftLen+1];
        
    int** len=new int*[leftLen+1];
        
    for (int i=0; i<=leftLen; i++) {
            result[i]
    =new int[rightLen+1];
            len[i]
    =new int[rightLen+1];
            result[i][
    0]=0;
            len[i][
    0]=0;
        }
        memset(result[
    0], 0, sizeof(int)*(rightLen+1));
        memset(len[
    0], 0, sizeof(int)*(rightLen+1));
        
    for (int i=1; i<=leftLen; i++) {
            
    for (int j=1; j<=rightLen; j++) {
                
    if (strcmp(left[i-1], right[j-1])==0) {
                    
    //back trace one

                    len[i][j]
    =len[i-1][j-1]+1;
                    result[i][j]
    =result[i-1][j-1]-(len[i-1][j-1]*len[i-1][j-1])
                            
    +(len[i][j]*len[i][j]);

                } 
    else if (result[i-1][j]>=result[i][j-1]) {
                    result[i][j]
    =result[i-1][j];
                } 
    else {
                    result[i][j]
    =result[i][j-1];
                }

            }
        }

        
    int ret= result[leftLen][rightLen];
        
    for (int i=0; i<=leftLen; i++) {
            delete[] result[i];
            delete[] len[i];

        }
        delete[] result;
        delete[] len;
        
    return ret;

    }

    int main() {
        
    char** lzwStr1=NULL;
        
    char** lzwStr2=NULL;
        string str1;
        string str2;
        
    int lzwLen1=0;
        
    int lzwLen2=0;
        getline(cin,str1);
        getline(cin,str2);
        
        parseToLZWLine(str1.c_str(), strlen(str1.c_str()), lzwStr1, lzwLen1);
        parseToLZWLine(str2.c_str(), strlen(str2.c_str()), lzwStr2, lzwLen2);

        cout
    <<calcLZW(lzwStr1, lzwLen1, lzwStr2, lzwLen2)<<endl;

        freeLZWStr(lzwStr1, lzwLen1);
        freeLZWStr(lzwStr2, lzwLen2);

        
    return 0;
    }



    posted @ 2008-05-31 23:20 DoubleH 閱讀(2427) | 評論 (3)編輯 收藏

    如果Web服務器需要頻繁傳送文件給客戶端時,大多數web容器會提供異步發送的支持,像IIS中的通過ServerSupportFunction(),Apache里面apr_sendfile(),Tomcat6.X通過設置Servlet Request的請求屬性等等。。。都可以做到異步發送文件,從而提高服務器性能。

    Jetty6.X默認也不提供相關支持,本文提供一種hack方法,僅供參考:

    先看測試Servlet:
    package com.yovn.labs.testweb;

    import java.io.File;
    import java.io.IOException;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.yovn.labs.sendfile.JettySendFile;
    import com.yovn.labs.sendfile.NormalSendFile;
    import com.yovn.labs.sendfile.SendFile;

    /**
     * 
    @author yovn
     *
     
    */
    public class SendFileServlet extends HttpServlet {

        
    protected void doGet(HttpServletRequest req, HttpServletResponse res)
                
    throws ServletException, IOException {
        
            
            
    try {
                
                File f
    =new File("D:\\workspace\\TEST.rar");//about 45M
                String action
    =req.getParameter("action");
                SendFile sf
    =null;
                
    if("1".equals(action))
                {
                    sf
    =new JettySendFile();
                }
                
    else
                {
                    sf
    =new NormalSendFile();
                }
                
    long start=System.currentTimeMillis();
                sf.doSend(req, res, f, 
    null);
                System.out.println(
    " service ok, action="+action+",use:"+(System.currentTimeMillis()-start)+"!!!");
            } 
    catch (Exception e) {
                
    throw new ServletException(e);
            }
          
        }
        
        

    }
    代碼很簡單明了,action=1時使用Jetty的異步發送,action=2時使用正常方式。

    下面是通過firefox直輸入地址回車后,下載文件,后臺的程序運行結果:
     service ok, action=1,use:62!!!
     service ok, action
    =2,use:10688!!!
     service ok, action
    =2,use:9063!!!
     service ok, action
    =1,use:47!!!
    當運行1時,實際上客戶端還沒有下完文件,但是該段代碼已經執行完了,IO的操作是異步的。
    當運行2時,客戶端下完代碼才執行完。

    以下是Jetty異步發送的代碼:
    package com.yovn.labs.sendfile;

    import java.io.File;
    import java.io.IOException;
    import java.lang.reflect.Field;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.mortbay.io.EndPoint;
    import org.mortbay.io.nio.NIOBuffer;

    /**
     * 
    @author yovn
     *
     
    */
    public class JettySendFile implements SendFile {

        
    static Field endpointField=null;
        
    static Class reqCls=null;
        
    static 
        {
            
    try {
                reqCls
    =Class.forName("org.mortbay.jetty.Request");
                endpointField
    =reqCls.getDeclaredField("_endp");
                endpointField.setAccessible(
    true);
            } 
    catch (Exception e) {
                
    // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
            
        
        


        
    public void doSend(HttpServletRequest req, HttpServletResponse res,File todo,String headerOpt)
                
    throws IOException {
            
            
    if(endpointField==null)throw new IOException("Jetty Not Available!!");
            
    if(!req.getClass().equals(reqCls))
            {
                
    throw new IOException("Not in Jetty Context!!");
            }
            EndPoint ep;
            
    try {
                ep 
    = (EndPoint)endpointField.get(req);
            
                
    if(headerOpt==null)
                {
                    headerOpt
    ="HTTP/1.1 200 OK \r\nContent-Type: APPLICATION/OCTET-STREAM\r\n"+
                          
    "Content-Disposition: attachment;filename=\""+todo.getName()+"\"\r\n"+
                          
    "Content-Length: "+todo.length()+"\r\n\r\n";
                }
                
    byte[] headerBytes=headerOpt.getBytes("UTF-8");
                NIOBuffer header
    =new NIOBuffer(headerBytes.length,false);
                header.put(headerBytes);
                
                NIOBuffer buffer
    =new NIOBuffer(todo);
                
                ep.flush(header, buffer, 
    null);
            } 
    catch (IllegalArgumentException e) {
                
    throw new IOException(e);
            } 
    catch (IllegalAccessException e) {
                
    throw new IOException(e);
            }
            
            
            
        }

    }

    正常發送文件的代碼:
    package com.yovn.labs.sendfile;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    /**
     * 
    @author yovn
     *
     
    */
    public class NormalSendFile implements SendFile {

        
    /* (non-Javadoc)
         * We simply ignore the 'headerOpt'
         * @see com.yovn.labs.sendfile.SendFile#doSend(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.io.File, java.lang.String)
         
    */
        
    public void doSend(HttpServletRequest req, HttpServletResponse res,
                File todo, String headerOpt) 
    throws IOException {
            res.setHeader(
    "Content-Type""APPLICATION/OCTET-STREAM");
            res.setHeader(
    "Content-Disposition""attachment;filename=\""+todo.getName()+"\"");
            res.setHeader(
    "Content-Length", todo.length()+"");
            res.setStatus(HttpServletResponse.SC_OK);
            OutputStream out
    =res.getOutputStream();
            InputStream in
    =new FileInputStream(todo);
            
            
    byte[] buffer=new byte[8192];
            
            
    int read=0;
            
    while((read=in.read(buffer))>0)
            {
                out.write(buffer, 
    0, read);
            }
            out.flush();
            in.close();
            
            

        }

    }


    posted @ 2008-03-29 01:54 DoubleH 閱讀(1770) | 評論 (0)編輯 收藏

    過道里依次掛著標號是1,2,3, ......,100的電燈泡,開始它們
    都是滅著的。當第一個人走過時,他將標號為 1 的倍數的電燈泡的開關
    線拉了一下;當第二個人走過時,他將標號為 2 的倍數的電燈泡的開關
    線拉了一下;當第三個人走過時,他將標號為 3 的倍數的電燈泡的開關
    線拉了一下;......  如此進行下去,當第一百個人走過時,他將標號為
    100 的倍數的電燈泡的開關線拉了一下。
    問:當第一百個人走過后,過道里亮著的電燈泡標號是多少?


    我的思路:
    設標號為K的燈泡被拉了L(K)次,那么當L(K)為奇數的時候,燈泡是亮的。
    那么那些標號被拉了奇數次呢?
    K=1時,很顯然是只拉了1次,最后是亮的。
    其次K>=2時,據題意,K號燈第1次,和第K次肯定是拉下了,其余的只會被第K的因子次拉,
    據因式分解定理,數K分解為
    K=p1^(n1)*p2^(n2)*.....pi^(ni)
    其中p1,p2,...pi為素數。
    那么,K有那些因子呢?
    其實可以考慮任一個因子,他可能是從n1個p1中選若干個(0個到n1個),從n2個p2中選若干個。。。。。(當全是0個的時候,這個特殊的因子是1)
    這樣,根據乘法原理,總共有L(K)=(n1+1)*(n2+1)*(n3+1).....
    比如,12=2^2*3
    一種有3*2=6個因子,他們是1,2,3,4,6,12.

    現在考慮要使L(K)為奇數,那么n1,n2,n3不能有一個是奇數,或則,有一個ni+1為偶數,而偶數與任何數相乘仍為偶數。
    從而,n1,n2,n3都為偶數,都能被2除。
    因為n1,n2,n3都為偶數,顯然該數必須是個平方數,可寫成K=(X)^2.
    從而,1,4,9,16,25,36,49,64,81,100最后是亮的。

    posted @ 2008-03-05 15:00 DoubleH 閱讀(2134) | 評論 (7)編輯 收藏

    去年也大概是這個時候寫了第一個Java2EXE,之后又加了寫特性,但是每次我看代碼都感覺慘不忍睹,很混亂,而且編譯,鏈接的過程也有點繞。
    現在又過了一年了,如果說上次版本的Load過程主要是靠Java(Java加密,解壓),那么這次基本把這些費時的操作全交給CPP了。
    好了,總結一下這次的改動
    1)Loader以及Starter完全是CPP代碼,結構很清晰了。
    2)加密以及解壓交給CPP,速度比以前快了。
    3)整合了JNative,這個是重點,下文詳述。
    4)生成工具用MFC寫,一個簡單的向導。

    OK,那么JNative是干什么的呢?
    官方的描述是 “JNative, Java framework for DLL access for Windows and Linux”
    就是說,有了這個框架,你訪問DLL里的方法就不再需要寫DLL了,只需要寫Java Code了,可能有人問它是怎么做到的呢?
    假如說你要訪問Kernel32.dll里的某個方法A,你首先需要這個方法的句柄,這個句柄就是通過new一個org.xvolks.jnative.JNative實例來保持的,
    類似如:
    org.xvolks.jnative.Native methodA=new org.xvolks.jnative.JNative("Kernel32.dll","A");
    有了這個句柄,你只要在上面設置參數,返回值,以及類型就可以調用它了。每個調用它上面的JNI里的本地方法就會自動來進行參數解析,解碼,調用到目標DLL方法,這個過程基本不可避免需要少量的匯編代碼。
    JNative為了可移植性,代碼是在Cygwin下可編譯的,沒有MSVC可編譯的版本。

    對此,本人改了部分代碼用于直接一起鏈接(主要是把GCC嵌入匯編改為對應的MSVC的嵌入匯編代碼),而不是讓JNative生成一個動態鏈接庫。

    如上,由于JNative改成了靜態庫,程序發布的時候,只要是通過Java2EXE Builder來創建成EXE的話,你就不需要那個JNativeCpp.dll文件了,只有一個EXE.

    你調試的時候可以用官方的版本,發布就只要你的代碼(JNative的class也都在集成在生成工具里,不需要你自己添加進來)。

    來看個簡單的例子,我們從Java代碼里取得當前進程的全路徑名:
    import org.xvolks.jnative.JNative;
    import org.xvolks.jnative.Type;
    import org.xvolks.jnative.exceptions.NativeException;
    import org.xvolks.jnative.pointers.Pointer;
    import org.xvolks.jnative.pointers.memory.HeapMemoryBlock;

    /**
     * DWORD GetModuleFileName(
     * HMODULE hModule,
     * LPTSTR lpFilename,
     * DWORD nSize
     *);

     * 
    @author yovn
     *
     
    */
    public class TestReadProcessPath {

        
    /**
         * 
         * 
    @param args
         * 
    @throws NativeException 
         * 
    @throws IllegalAccessException 
         
    */
        
    public static void main(String[] args) throws NativeException, IllegalAccessException {
            JNative v
    =new JNative("Kernel32.dll","GetModuleFileNameA");
            
    int i = 0;
            v.setRetVal(Type.INT);
            Pointer pName 
    = new Pointer(new HeapMemoryBlock(1024));
            
            v.setParameter(i
    ++0);//module handle
            v.setParameter(i++, pName);//pFileName
            v.setParameter(i++1024);//nSize
            v.setRetVal(Type.INT);
            v.invoke();
            
    int ret = Integer.parseInt(v.getRetVal());
            
    if (ret == 0) {
                
    // return "null";
                System.err.println(
                        
    "GetModuleFileName failed!");
            } 
    else {
                
                String path 
    = pName.getAsString().substring(0,
                        ret);
                pName.dispose();
                v.dispose();
                System.out.println(
    "current process's path is:"+path);
            }
        }

    }

    編譯,把這個文件單獨打包成一個jar文件,下面是個用這個工具生成EXE的截圖:
    生成EXE向導第一步
    生成 EXE向導第二步



    請從這里下載 Java2EXE Builder Platform











    posted @ 2008-02-26 00:31 DoubleH 閱讀(1819) | 評論 (7)編輯 收藏

         摘要: 紅黑樹可能是要考慮情況最多的BST樹了,它有自己的規則(見代碼的注釋),通過這些規則可以保證花費較小的代價來達到相對平衡。 注意,紅黑樹仍然不是平衡樹,但是統計性能要好于AVL樹。 要保持紅黑樹的規則,主要通過兩類操作,一類是換色,一類還是旋轉。 紅黑樹插入主要要解決紅-紅沖突,而刪除主要則解決“雙黑” 同樣,紅黑樹的刪除節點實現是最復雜的,不過,復雜也就在于考...  閱讀全文
    posted @ 2007-12-20 18:25 DoubleH 閱讀(8497) | 評論 (20)編輯 收藏

         摘要: 伸展樹與半伸展樹屬于自組織的數據結構,能按訪問頻率調整節點的位置 調整一般通過如下方式: 1)繞根的單旋轉,跟AVL的單旋轉類似 2)一字型旋轉(ZigZig Rotation) 3)之字形旋轉(ZigZag Rotation) 旋轉操作較簡單,有點點繁瑣。 半伸展樹不做完全的一字型旋轉,它只讓父節點繞祖父節點做單旋轉。 不管怎樣,每次訪問(插入/查找 ,刪除時展開被刪除父節...  閱讀全文
    posted @ 2007-12-19 00:39 DoubleH 閱讀(2419) | 評論 (0)編輯 收藏

         摘要: AVL樹的是一種平衡的二叉搜索樹。每次插入,刪除的時候需要一個局部的平衡化操作。 實現AVL樹的插入操作一般不是很難,清楚的理解了平衡因子以及旋轉操作實現起來就沒多大問題了。 難點一般在于刪除操作的實現,教科書上一般用很大的篇幅來詳細說明各種情況,看起來很凌亂,理解起來很是費勁。考慮到可以把刪除操作看成插入操作的逆操作,這里我給出另一種較為清晰的實現方式: 1)刪除的時候做一個標記的過程 ...  閱讀全文
    posted @ 2007-12-18 18:30 DoubleH 閱讀(3626) | 評論 (0)編輯 收藏

    僅列出標題
    共5頁: 上一頁 1 2 3 4 5 下一頁 
    主站蜘蛛池模板: 亚洲一区二区三区乱码A| 国产精品一区二区三区免费| 亚洲成AV人片在| 亚洲高清无码专区视频| 在线看片免费不卡人成视频| 久久99热精品免费观看牛牛| 九九免费久久这里有精品23| 亚洲GV天堂GV无码男同| 国产精品亚洲专区在线观看| 亚洲国产人成网站在线电影动漫 | 亚洲精品成人久久久| 毛片免费视频观看| 18禁网站免费无遮挡无码中文| a级片免费在线播放| 一个人看的www免费高清| 国产精品自拍亚洲| 亚洲AV色无码乱码在线观看| 亚洲最大成人网色香蕉| 亚洲国产美女在线观看| 久久夜色精品国产噜噜噜亚洲AV | h在线看免费视频网站男男| 色多多免费视频观看区一区| 亚洲av无码专区在线电影天堂| 学生妹亚洲一区二区| 亚洲人成777在线播放| 亚洲国产日产无码精品| 亚洲成人福利在线观看| 亚洲第一页中文字幕| 亚洲码一区二区三区| 亚洲国产精品网站久久| 亚洲成人黄色在线观看| 亚洲AV成人无码天堂| 久久精品国产亚洲AV忘忧草18| 亚洲人xxx日本人18| 中文日韩亚洲欧美制服| 在线a亚洲老鸭窝天堂av高清| 亚洲精品无码aⅴ中文字幕蜜桃| 亚洲AV无码国产一区二区三区 | 免费的涩涩视频在线播放| 爽爽日本在线视频免费| 国产一级淫片免费播放电影|