【总结:】
思路:汉字的unicode编码都是负数
注意事项:字符串的输入编码和输出编码、已经eclipse等编译工具的编码都会影响结果 所有最好把编码设置一下或统一;
【自己的代码】
1 package text; 2 import java.io.IOException; 3 import java.util.Scanner; 4 public class StringTest { 5 /* 6 * 思路:汉子编码为负数 7 * 注意:不同编码的字节位数不同,需要区分对待 8 */ 9 public static void main(String[] args) throws IOException { 10 int count=0; 11 //输入字符串和截取长度 12 Scanner sc=new Scanner(System.in); 13 System.out.println("请输入字符串:"); 14 String s=sc.nextLine(); 15 byte[] b=s.getBytes("GBK"); 16 System.out.println("请输入截取长度:"); 17 int num=sc.nextInt(); 18 if(num>b.length||num<0){ 19 System.out.println("输入数字不正确!"); 20 return ; 21 } 22 //统计截取的字符串包括多少负值,一边避免半个汉字 23 for(int i=0;i<num;i++){ 24 if(b[i]<0){ 25 count++; 26 } 27 } 28 //因为是GBK,所有模2来判断 29 if(count%2==0){ 30 System.out.println("截取的字符串为:"+new String(b,0,num,"GBK")); 31 }else{ 32 System.out.println("截取的字符串为:"+new String(b,0,num-1,"GBK")); 33 } 34 } 35 }
【网上参考】
今天去一个公司面试,碰到一个很久前练过的题目,竟然没答出来,感觉好囧!!回来好好研究一番,贴上代码:
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); } }