基础试题,还请各位指教~
Question:编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
* 例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
基本思路都是根据GBK码表中中文是由两个负的byte型数值表示来切割。
网上的解法是根据判断取的字节是否是奇数,是奇数再去区分会不会截断中文但是这个对出现连续中文的情况就解决不了,
比如”a一二三四“当截取字节为3,5,7时本来刚刚好都会在字节中向下走一位取到半个字符,详情请看-->http://bbs.itheima.com/thread-145368-1-1.html
**** 在最近的基础测试上, 我想出了一个新的解法。这种解法的思路是设定一个静态全局boolean型变量flag做为标志,当遍历字符串产生的byte[]时,每经过一个负数就把flag反置一次,所以碰到连续两个负的值时会翻转成true,利用这个特点,每次遍历n个(需要切割的字节数)字节,查看flag状态,是true,则直接截取到当前位置,若为负则截取到当前位置的前一个位置。
- //设定一个为true的标志来表示是否已连续遍历两个负数
- public static boolean flag = true;
- public static void mySplit(String str , int num)
- {
- //定义一个字节数组用于存放str按GBK所得字节
- byte[] by = null;
- try{
- by = str.getBytes("GBK");
- }
- catch(UnsupportedEncodingException e){
- throw new RuntimeException("不支持的编码格式");
- }
- int x =0;
- //从x开始遍历得到的字节数组
- while(x<by.length){
- //限制条件,防止脚标越界
- if(x+num<by.length){
- //每次从字节数组中遍历num个字节
- for(int y=0;y<num;y++){
- //如果遍历到汉字的字节更改标志
- if(by[x+y]<0)
- changeFlag();
- }
- //如果遍历后flag为true 表示角标没有处在汉字的第二个字节上
- //如果遍历后flag为false 表示角标处在汉字的第二个字节上
- if(flag){
- try{
- //打印从x开始数num个字节所表示的字符串
- String s1 = new String(by, x, num, "GBK");
- System.out.println(s1);
- }
- catch(UnsupportedEncodingException e){
- throw new RuntimeException("不支持的编码格式");
- }
- //使下次循环从x+num开始
- x=x+num;
- }
- else{
- try{
- //打印从x开始数num-1个字节所表示的字符串,避免把汉字切开
- String s1 = new String(by, x, num-1, "GBK");
- System.out.println(s1);
- }
- catch(UnsupportedEncodingException e){
- throw new RuntimeException("不支持的编码格式");
- }
- //使下次循环从x+num-1开始
- x=x+num-1;
- //重置flag
- flag=true;
- }
- }
- //当遍历到最后时剩下的字节数不够num个时
- else{
- try{
- //打印从x开始到结尾字节所表示的字符串
- String s1 = new String(by, x, by.length-x, "GBK");
- System.out.println(s1);
- //结束循环
- x=by.length;
- }
- catch(UnsupportedEncodingException e){
- throw new RuntimeException("不支持的编码格式");
- }
- }
- }
- }
- //用于改变标志
- public static void changeFlag(){
- flag=!flag;
- }
复制代码
代码有点长,好多trycatch, 还请见谅。
|
|