神州灵云 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 文章被收录于专栏
记录秋招...


