一个面试题:按字节截取字符串避免半个汉字

时间:2023-01-12 11:10:07

今天去一个公司面试,碰到一个很久前练过的题目,竟然没答出来,感觉好囧!!回来好好研究一番,贴上代码:

String类的length()方法是以unicode代码单元,换言之就是char的个数为来统计的。所以使用subString等截取出来的子串都不会出现半个汉字的情况,因为java一个char类型可以存放一个汉字(2个字节)。而如果以字节byte来截取字符串,就会出现半个汉字的情况。

这道题就是这样的要求:

编写一个截取字符串的方法,参数为一个字符串和字节数,返回按字节数截取的子串,保证汉字不被截半个。如:输入"我abc"、4,应该截为"我ab"。输入"我abc汉def"、6,应该截为"我abc"

思路:汉字的unicode编码都是负数,如果这些负数字节在截取的字节数组中成对出现,说明不会截取到半个汉字。如果不是成对出现,则会截取到半个汉字,需要将最后一个字节舍去。

public class StrTest {
    /***
     * 按字节数截取字符串, 不能截出半个汉字, 如果是半个汉字则舍去!
     * 
     * @param source
     * @param num
     * @return
     */
    public static void cutString(String source, int byteCount) {
        byte[] byteArr = source.getBytes();
        int count = 0;
        // 统计要截取的那部分字节中负数的个数
        for (int i = 0; i < byteCount; i++) {
            if (byteArr[i] < 0) {
                count++;
            }
        }
        // 负数成对出现 则不会出现半个汉字
        if (count % 2 == 0)
            System.out.println(new String(byteArr, 0, byteCount));
        // 负数个数不是偶数,则有半个汉字
        else
            System.out.println(new String(byteArr, 0, byteCount - 1));
    }

    public static void main(String[] args) {
        cutString("我aabc中国cccr", 6);
    }

}