面试题,做一个汇总
1、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,应该输出为“我ABC”而不是“我ABC+汉的半个”。
要解决这个问题要知道以下几点
- 按题中的例子,得知这里的一个字符应该是由两个字节表示,符合这个条件的编码方式为‘GBK’编码,所以得到的字节数组要用gbk编码获得,即byte[] bytes = str.getBytes(“gbk”);
- GBK 亦采用双字节表示,总体编码范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,剔除 xx7F 一条线。总计 23940 个码位,共收入 21886 个汉字和图形符号,其中汉字(包括部首和构件)21003 个,图形符号 883 个。
81的二进制为:10000001 ,最高位为1所以汉字的首字节一定是负数
(3)可以通过new String(bytes,0,byteLen-1,“gbk”)由byte数组得到一个指定编码字符集的字符串;
public static void splitString(String str,int byteLen) throws UnsupportedEncodingException {
if ( str.isEmpty() || byteLen <= 0)
return;
byte[] bytes = str.getBytes("gbk");//指定gbk编码字符集
if ( byteLen >= bytes.length ) {
System.out.println( new String(bytes,0,bytes.length,"gbk") );
return;
}
if ( bytes[byteLen -1] >= 0 ) {
System.out.println( new String(bytes,0,byteLen,"gbk") );
} else {
for ( int i = 0 ; i < byteLen ; i++ ){
//判断最后一个字节是一个字符的首字节还是尾字节,是首字节则舍去
if ( bytes[i] < 0 && ++i == byteLen) {
System.out.println( new String(bytes,0,byteLen-1,"gbk") );
return;
}
}
System.out.println( new String(bytes,0,byteLen,"gbk") );
}
}
//测试代码
public static void main(String[] args) throws UnsupportedEncodingException {
System.out.println(Arrays.toString("我".getBytes("gbk")));//[-50, -46]
System.out.println(Arrays.toString("丂".getBytes("gbk")));//[-127, 64]
splitString("我ABC汉DEF", 1);//
splitString("我ABC汉DEF",