神州灵云 java笔试
一道编程实现题 ,要求用时1坤h:
LC地址是一种私有协议的地址,通常写成4组,每组为四个十六进制数的形式,由“#”来分隔,因此它占用的空间是64比特,也就是8字节。比如:Ad80#0000#0000#0002 是一个合法的LC地址,这个地址比较长,看起来不方便也不易于书写,零压缩法可以用来缩减其长度。对于LC地址有如下压缩规范:
- 如果4组中有几(>=1)个连续组的值都是0,那么这些0就可以简单的以##来表示,上述地址就可写成Ad80##0002。这里要注意的是,零压缩法只能简化值为0的连续组,比如AD80的最后的这个0,不能被简化。
- 零压缩法只能用一次,对于0000#1234#0000#4321来说,如果对1234前的1组0000进行了压缩,所以1234后面的0000就不能再次压缩简化,即压缩为##1234#0000#4321。当然也可以在1234后面使用##,这样的话前面的1234前的1组0000就不能压缩了,地址就变为0000#1234##4321。这个限制的目的是为了能准确还原被压缩的0,否则就无法确定每个##代表了多少个0。
- 每组数字里的前导零可以省略,因此 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 文章被收录于专栏
记录秋招...