神州灵云 java笔试

一道编程实现题 ,要求用时1坤h:

LC地址是一种私有协议的地址,通常写成4组,每组为四个十六进制数的形式,由“#”来分隔,因此它占用的空间是64比特,也就是8字节。比如:Ad80#0000#0000#0002 是一个合法的LC地址,这个地址比较长,看起来不方便也不易于书写,零压缩法可以用来缩减其长度。对于LC地址有如下压缩规范:

  1. 如果4组中有几(>=1)个连续组的值都是0,那么这些0就可以简单的以##来表示,上述地址就可写成Ad80##0002。这里要注意的是,零压缩法只能简化值为0的连续组,比如AD80的最后的这个0,不能被简化。
  2. 零压缩法只能用一次,对于0000#1234#0000#4321来说,如果对1234前的1组0000进行了压缩,所以1234后面的0000就不能再次压缩简化,即压缩为##1234#0000#4321。当然也可以在1234后面使用##,这样的话前面的1234前的1组0000就不能压缩了,地址就变为0000#1234##4321。这个限制的目的是为了能准确还原被压缩的0,否则就无法确定每个##代表了多少个0。
  3. 每组数字里的前导零可以省略,因此 aD80##0002等价于aD80##2,另外,0#00#000#1234 可以缩写成 ##1234。

解决类 :

package com.huanf;

public class LCAddress {
    private long longV ;
    private String strV ;

    public long getLongV() {
        return longV ;
    }

    // 返回LC地址的10进制整数
    public void setLongV(long longV) {
        this.longV = longV ;
    }

    // 返回带#号的LC地址字符串
    public String getStrV() {
        return strV ;
    }

    public void setStrV(String strV) {
        this.strV = strV ;
    }

    public LCAddress() {

    }

    // 构造函数A:从一个字符串(例如"1#2#3#4")开始构造LC地址
    public LCAddress(String str) {
        String s = toAll(str) ;
        this.strV = s ;
        this.longV = strTolong(s) ;
    }

    // 构造函数B:从long型的10进制构造LC地址
    public LCAddress(long v) {
        this.longV = v ;
        this.strV = longTostr(v) ;
    }

    private String toAll(String str){
        if(str.equals("##")){
            return "0000#0000#0000#0000" ;
        }
        StringBuilder res = new StringBuilder() ;
        boolean tag = false ;
        // 分割 , 保留最后的空字符串
        String[] sp = str.split("#" , -1) ;
        int n = sp.length ;
        // ##4
        for(int i=0;i<n;i++){
            String s = sp[i] ;
            // System.out.println(s);
            if(s.isEmpty()){
                if(i==0){ // 如果第一个是空的
                    if(n==5){ //只有第一个是空的
                        // ##2#3
                        res.append("0000") ;
                        i++ ;
                    }else {
                        int len = 0 ;
                        if(n==4) len = 1 ;
                        else len = 2 ;
                        while(len-->0) res.append("0000#") ;
                        res.append("0000") ;
                        i++ ;
                    }
                }else if(i<n-1){
                    int len = 4 - n ;
                    while(len-->0) res.append("0000#") ;
                    res.append("0000") ;
                }else{
                    res.append("0000") ;
                }
            }else{
                while(s.length()<4) s='0'+s;
                res.append(s) ;
            }
            if(i!=n-1) res.append("#") ;
        }
        // System.out.println(res) ;
        return res.toString() ;
    }

    // 4位16进制字符串 转长整型
    private long get(String s){
        long res = 0 ;
        for(int i=0;i<4;i++){
            int d = Character.digit(s.charAt(i),16) ;
            res = (res<<4) | d ;
        }
        return res ;
    }

    // 将LC地址字符串转换为long型
    private long strTolong(String str) {
        // 采用位运算
        long ans = 0 ;
        String[] ps = str.split("#") ;
        int ms = 48 ;
        for(String s : ps){
            // System.out.println(get(s)) ;
            ans |= get(s) << ms ;
            ms-=16 ;
        }
        return ans ;
    }

    private String longToHex(long x){
        if (x == 0) {
            return "0000";
        }
        StringBuilder sb = new StringBuilder();
        while (x != 0) {
            long rd = x % 16 ; // 余数 , 也就是低四位
            char c = (char) (rd < 10 ? '0' + rd : 'A' + (rd - 10)) ;
            sb.insert(0, c);
            x >>>= 4;
        }
        return sb.toString();
    }

    // 将long数转换为LC地址字符串
    private String longTostr(long v) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 4; i++) {
            long x = v & 0xFFFF;
            v >>= 16;
            // x转换为字符串
            sb.append(longToHex(x)).append("#");
        }
        // 去掉最后一个多余的#
        sb.setLength(sb.length() - 1);
        return sb.toString();
    }

}

测试类 :

package com.huanf;


public class test {

    public static void main(String[] args) {
        long x = 1090921030L ;
        LCAddress lcAddress = new LCAddress(x) ;
        long v = lcAddress.getLongV();
        String s = lcAddress.getStrV();
        System.out.println(v) ;
        System.out.println(s);

        System.out.println("-------------------");

        String str = "1#2#3#4" ;
        LCAddress lc1 = new LCAddress(str) ;
        long v1 = lc1.getLongV();
        String s1 = lc1.getStrV();
        System.out.println(v1);
        System.out.println(s1);

        System.out.println("------------------");

        String str2 = "##4" ;
        LCAddress lc2 = new LCAddress(str2) ;
        long v2 = lc2.getLongV();
        String s2 = lc2.getStrV();
        System.out.println(v2);
        System.out.println(s2);

        System.out.println("-----------------");

        String str3 = "##3#4" ;
        LCAddress lc3 = new LCAddress(str3) ;
        long v3 = lc3.getLongV();
        String s3 = lc3.getStrV();
        System.out.println(v3);
        System.out.println(s3);

        System.out.println("-----------------");

        long x1 = 9999999999987655L;
        LCAddress lcAddress1 = new LCAddress(x1) ;
        long v4 = lcAddress1.getLongV();
        String s4 = lcAddress1.getStrV();
        System.out.println(v4) ;
        System.out.println(s4);
    }
}

#软件开发笔面经#
秋招joker 文章被收录于专栏

记录秋招...

全部评论

相关推荐

点赞 1 评论
分享
牛客网
牛客企业服务