Java編程題目-3:字符串自定義encode(),decode()

這是去一個小公司遇到的機試題,當時花了一個多小時寫完的,但是有很多細節沒考慮好,題目如下:

請您用Java語言實現兩個函數encode()和decode(),分別實現對字符串的變換和復原.變換函數encode()順序考察已知字符串的字符,按以下規則逐組生成新字符串:
(1)若已知字符串的當前字符不是大於0的數字字符,則複製該字符於新字符串中;
(2)若已知字符串的當前字符是一個數字字符,且它之後沒有後繼字符,則簡單地將它複製到新字符串中;
(3)若已知字符串的當前字符是一個大於0的數字字符,並且還有後繼字符,設該數字字符的面值爲n,則將它的後繼字符(包括後繼字符是一個數字字符)重複複製n+1次到新字符串中;
(4)以上述一次變換爲一組,在不同組之間另插入一個下劃線’_’用於分隔;
(5)若已知字符串中包含有下劃線’_’,則變換爲 ”\UL” 。
復原函數decode()做變換函數encode()的相反的工作.按照上述規則逆運算,變回原來的字符串。
例如:encode()函數對字符串24ab_2t2的變換結果爲 444_aaaaa_a_b_\UL_ttt_t_2


今天再寫就順暢多了,速度也快很多,先看encode()代碼如下:

public String encode(String str){
        int len = str.length();
        StringBuilder sb = new StringBuilder();
        char c;// current char
        char cnext;// next char
        for(int i=0;i<len;i++){
            c = str.charAt(i);

            if((c<='0' || c>'9')&& c!='_'){// 判斷1
                sb.append(c);
                if(i!=(len-1)){
                    sb.append("_");
                }
                continue;// 當0是最後一位的時候,同時滿足了判斷1和判斷2,所以加上continue,防止重複拼接。
            }
            if(c>='0' && c<='9' && i==(len-1)){// 判斷2
                sb.append(c);
                if(i!=(len-1)){
                    sb.append("_");
                }
            }
            if(c>'0' && c<='9' && i!=(len-1)){// 判斷3
                cnext = str.charAt(i+1);
                int c_int = c-48;
                for(int j=0;j<=c_int;j++){
                    sb.append(cnext);
                }
                if(i!=(len-1)){
                    sb.append("_");
                }
            }
            if('_'==c){// 判斷4
                sb.append("\\UL");
                if(i!=(len-1)){
                    sb.append("_");
                }
            }
        }
        return sb.toString();
    }

要考慮到每個部分拼接後那個‘’作爲分隔符拼接上,並且在最後一個部分後不再拼接;對於“當前字符不是大於0的數字字符”,要把‘’也考慮進去,不然結果中會多出很多’_’;對於取出的每個char型的字符,有的需要轉換成int型,char的‘0’-‘9’減去48後就是對應的int型0-9的數字。


下面就是deCode()方法了,decode()方法逆向思考,不太好處理。代碼如下:

public String deCode(String str){
        String[] parts = str.split("_");
        int len = parts.length;
        StringBuilder sb = new StringBuilder();
        // 初始化StringBuilder
        for(int k=0;k<len;k++){
            sb.append("0");
        }

        String part;// parts數組的單個元素:part
        int part_len;
        char c;// part中的單個字符

        // 遍歷parts的每個部分
        for(int i=0;i<len;i++){
            part = parts[i];
            part_len = part.length();// part的長度
            c = part.charAt(0);
            if(part_len>1){
                if(c>='0' && c<='9'){
                    sb.setCharAt(i, (char)(part_len-1+48));
                    sb.setCharAt(i+1, c);
                }
                if(!(c>='0' && c<='9') && c!='\\'){
                    sb.setCharAt(i, (char)((part_len-1)+48));
                    sb.setCharAt(i+1, c);
                }
            }else{
                sb.setCharAt(i, c);
            }
            if("\\UL".equals(part)){
                sb.setCharAt(i,'_');
            }
        }
        return sb.toString();
    }

decode()逆向思考比較難,我覺得先考慮就是將字符串split(),再對拆分出的每一部分進行解析:如果長度大於1,那麼就取出裏面的字符,逐個判斷處理;而長度不大於1,就是單個字符了;餘下的就是比較“\UL”了。

總結下經驗就是根據題目要求慢慢剖析,整理條件,就可以避免遺漏了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章