黑马程序员技术交流社区

标题: 昨天有到题实在不知道怎么写 求代码 [打印本页]

作者: Hi天天向上    时间: 2014-5-29 12:39
标题: 昨天有到题实在不知道怎么写 求代码
10、编写函数,从一个字符串中按字节数截取一部分,         *   但不能截取出半个中文(GBK码表),         *   例如:从“HM程序员”中截取2个字节是“HM”,         *   截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文


哪位大神能好好说下GBK编码么  



作者: 海世山盟    时间: 2014-5-29 14:12
本帖最后由 伍叶竹 于 2014-5-29 14:30 编辑

在gbk编码里面汉字是两个负数。因此可以用将字符串转换成字节,判断每一位的正负来定夺汉字和非汉字。具体代码如下
class  splitOfString

{
        public static void main(String[] args)
        {
                String s="嗯okg你好我是hello";
                 split_String(s,6);
        }

        public static void split_String(String s,int key)
        {
        int count=0;//记录出现负数的次数
        byte[] b=s.getBytes();
        
                if(key>=1)
                {
                        for(int x=0;x<key;x++){
                if(b[x]<0)
                        count++;//
                        }
                if(b[key-1]<0&&(count%2==1))//  当count为奇数时,说明最后一位是一个汉字的半个字节。那么就需要舍去最后一位
                        {
                        System.out.println(new String(b,0,--key));
                        }
                else
                        {
                System.out.println(new String(b,0,key));
                        }
                }
        
               
               
                }
        }
作者: 海世山盟    时间: 2014-5-29 14:13
上边红色部分写错了 ,是当count为奇数的时候。
作者: fenzheng    时间: 2014-5-29 14:18


        public static String bSubstring(String s, int length) throws Exception {
                // getBytes(String charsetName):将此字符串转换为一个字节序列使用指定的字符集,结果存储到一个新的字节数组
                byte[] bytes = s.getBytes("Unicode");//以Unicode来解码这个字符串,得到一个byte[]
                int n = 0; // 表示当前的字节数
                int i = 2; // 要截取的字节数,从第3个字节开始
                for (; i < bytes.length && n < length; i++) {

                        // 奇数位置,如3、5、7等,为UCS2编码中两个字节的第二个字节

                        if (i % 2 == 1) {
                                n++; // 在UCS2第二个字节时n加1
                        } else {
                                // 当UCS2编码的第一个字节不等于0时,该UCS2字符为汉字,一个汉字算两个字节
                                if (bytes[i] != 0) {
                                        n++;
                                }
                        }
                }

                // 如果i为奇数时,处理成偶数

                if (i % 2 == 1) {
                        // 该UCS2字符是汉字时,去掉这个截一半的汉字
                        if (bytes[i - 1] != 0)
                                i = i - 1;
                        // 该UCS2字符是字母或数字,则保留该字符
                        else
                                i = i + 1;
                }

                return new String(bytes, 0, i, "Unicode");

        }

        public static void main(String[] args) throws Exception {
                String s = "HMh程序员";
                String ss = Test10.bSubstring(s, 3);// 调用bSubstring()方法传入两个参数:第一个是要操作的字符串第二个是要截取的长度
                System.out.println(ss);
        }

作者: Hi天天向上    时间: 2014-5-29 16:19
海世山盟 发表于 2014-5-29 14:12
在gbk编码里面汉字是两个负数。因此可以用将字符串转换成字节,判断每一位的正负来定夺汉字和非汉字。具体 ...

灰常感谢哦
作者: Hi天天向上    时间: 2014-5-29 16:20
fenzheng 发表于 2014-5-29 14:18
public static String bSubstring(String s, int length) throws Exception {
                // getBytes(String cha ...

虽然用的是unicode编码 但还是灰常感谢你的回答
作者: JavaStudy770    时间: 2014-5-30 13:22
这是我写的:

public class Test10 {

        public static void main(String[] args) {
                //被截取的字符串
                String str = "HM黑马";
                //以byte形式截取3个字符(实则截取了2个字符),并赋给result
                String result = split(str,3);
                //打印结果
                System.out.println(result);
        }
       
        //截取方法,参数str为被截取的字符串,length为截取的长度
        public static String split(String str, int length) {
                //得到表示str的byte数组
                byte[] arr = str.getBytes();
                //判断要截取的字符串的最后一个字符是不是字母。如果小于0则肯定不是字母,
                //因为a的US-ASCII编码为97,A为65
                //并且汉字的GBK编码都大于128,如果将其转化成byte,由于损失精度,得到的值必小于0
                if(arr[length]<0) {
                        //如果要截取的字符串的最后一个字符不是字母,则去掉该字符
                        length -= 1;
                }
                //使用String的构造方法得到要截取的字符串
                String result = new String(arr,0,length);
                //返回
                return result;
        }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2