java:关于字符编码的试题

本文介绍了一种算法,用于从给定的GBK编码字符串中按字节数截取部分中文字符,确保截取时不出现半个中文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
        例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
思路:GBK编码中,一个字母占一个字节,切最高位为0;一个汉字占两个字节,最高位都为为1.
*/
import java.util.*;

class Test10
{
        public static void main(String[] args) throws Exception
        {
                String str = "你好HM程序员";

                //c从str中截取前3个字节,并返回字符串
                String sub = backString(str, 3);
                
                System.out.println(sub);
        }
        
        //取字符创str的前n个字节的字符串
        public static String backString(String str, int n) throws Exception
        {
                //字符串转换为字节数组
                byte[] buf = str.getBytes("GBK");
                
                //存储返回的子串
                String sub = null;
                
                //记录每个字节的最高位
                StringBuilder sb = new StringBuilder(); //
        
                for(byte b : buf)
                {
                        String s = Integer.toBinaryString(b&128);
                        char[] ch = s.toCharArray();
                        
                        sb.append(ch[0]);        
                }
                //System.out.println(sb);
                
                //第n个字节的最高位
                char c = sb.charAt(n-1);        
                //System.out.println(c);
                
                //如果第n个字节最高位为0,则返回前n个字节的字符串
                if(c == '0')
                {
                        sub = new String(buf, 0, n, "GBK");
                }
                
                //如果第n个字节最高位为1,则需要记录前n个字节最高位为1的个数count
                //count为偶数,则该字节只是一个中文字符的一部分,只需返回前n-1个字节的字符串形式
                //count为奇数,则第n-1个字节的最高位必也为1,这两个字节正好形成一个中文字符,返回前n个字节的字符串形式
                else
                {
                        int count = 0;
                        //记录'1'在sb中的第n个字符之前出现的次数
                        char[] s1 = sb.toString().toCharArray();
                        
                        for(int i = 0; i < n-1 ; i++)
                        {
                                if(s1[i] == '1')
                                {
                                        count++;
                                }
                        }
                        
                        if(count%2 == 0)
                        {
                                sub = new String(buf, 0, n-1, "GBK");
                        }
                        else
                        {
                                sub = new String(buf, 0, n, "GBK");
                        }
                }
                
                return sub;
        
        }
}

 

 


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值