A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wx999 中级黑马   /  2015-5-9 14:58  /  712 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 wx999 于 2015-5-9 22:59 编辑

题目:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个。如输入:"我ABC"和4,应该截取“我AB”,输入“我ABC汉DEF”和6,应该输出“我ABC”,而不是“我ABC+汉的半个”。
代码
  1. import java.util.*;
  2. class Test
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                
  7.                 jieduan();
  8.         }
  9.         public static void jieduan()
  10.         {
  11.                 Scanner in = new Scanner(System.in);

  12.                 System.out.println("请输入字符串:");

  13.                 String str = in.next();

  14.                 System.out.println("请输入截断位置:");

  15.                 int num = in.nextInt();

  16.                 byte[] b = str.getBytes();

  17.                 int len = b.length;

  18.                 if(len>num)
  19.                 {
  20.                         if(b[num]>0)
  21.                         {
  22.                                 String s = new String(b,0,num);
  23.                                 System.out.println(s);
  24.                         }
  25.                         else
  26.                         {
  27.                                 String s = new String(b,0,--num);
  28.                                 System.out.println(s);
  29.                         }
  30.                 }
  31.                 else
  32.                         System.out.println("输入错误!");
  33.         }
  34. }
复制代码
虽然满足了题目的示例,但如果输入"String是一种基本的数据类型",截断位置是奇数是正确的,如果是偶数就会有错误,如输入16,显示结果是 String是一种基? 。
这个程序该怎么改,或者还有其他办法来完成这题吗?求教各位大神

5 个回复

倒序浏览

  1. package basetest;
  2. import java.io.*;
  3. /*编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表),例如:从“HM程序员”中
  4. * 截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是“HM”而不要出现半个中文。
  5. * 思路:
  6. * 1.将指定的字符串变成字节数组
  7. * 2.通过判断指定字节数组的长度来返回相应的字符串
  8. * 3.截取字节生成新字符串和源字符串上的相同字符比较,一样说明没有半个汉字,返回字符串,不一样说明有
  9. *   半个汉字,返回-1后的字符串。
  10. */
  11. public class Test10 {
  12.         public static void main(String[] args) {
  13.                 String s ="heima程序员很牛逼!";//源字符串
  14.                 System.out.println(getString(s,9));
  15.         }
  16.         public static String getString(String str,int num) {
  17.                 //将字符串转换成字节数组时,需要处理不支持GBK机器上的异常
  18.                 byte[] buf =null;
  19.                 try{
  20.                         buf =str.getBytes("GBK");//将指定字符串变成字节数组
  21.                 }
  22.                 catch(IOException e){
  23.                         e.printStackTrace();//捕获异常
  24.                 }
  25.                 if(num<0)  //指定获取的字节数如果小于0,抛Runtime异常
  26.                         throw new RuntimeException("获取字节个数为负数,错误");
  27.                 else if (num>str.length())//截取字节数大于原字符串长度,返回原字符串
  28.                         return str;
  29.                 else {
  30.                         String s = new String(buf,0,num);//截取字节数组转换成字符串
  31.                         int length = s.length();
  32.                         if(s.charAt(length-1)!=str.charAt(length-1)){//转换后的字符串和原字符串相同位置的字符比较,相同返回原串,
  33.                                                                                                                  //不相同说明截到半个汉字,返回从0到截取数字-1位置处的字节转换成字符串。                               
  34.                                 s = s.substring(0,length-1);
  35.                                 return s;
  36.                         }
  37.                         return s;
  38.                        
  39.                 }
  40.                        
  41.                 }
  42.                
  43.        
  44. }
复制代码

回复 使用道具 举报
  1. public static void main(String[] args) throws Exception {
  2.                 String str = "HM程序员cdd深圳校区";
  3.                 int num = trimGBK(str.getBytes("GBK"), 5);
  4.                 System.out.println(str.substring(0, num));
  5.         }
  6.         public static int trimGBK(byte[] buf, int n) {
  7.                 int num = 0;
  8.                 Boolean bChineseFirstHalf = false;
  9.                 for (int i = 0; i < n; i++) {
  10.                         if (buf[i] < 0 && !bChineseFirstHalf) {
  11.                                 bChineseFirstHalf = true;
  12.                         } else {
  13.                                 num++;
  14.                                 bChineseFirstHalf = false;
  15.                         }
  16.                 }
  17.                 return num;
  18. }
复制代码
回复 使用道具 举报
如果截取到汉字的一半,那么这半个字的Ascii码肯定不再 0-127,所以可以判断这半个字的 第 n-1这个字符的ASCII码,如果这个值在 0-127, 那么这个n-1就要着,直接截取就可以了
如果这个值不再0-127, 那么从这个字符为起点向前变量, 到遇到一个0-127的结束,看看变量中有几个不再0-127的数, 如果是偶是这个n-1就保存,如果是奇数,这个n-1就是半个字符,舍弃掉

  1. public static String subStr(String str, int n)
  2.         {
  3.                 if(n<1)
  4.                 {
  5.                         return null;
  6.                 }
  7.                
  8.                 byte[] buf = str.getBytes();
  9.                 byte by1 = buf[n-1];

  10.                 int count = 0;
  11.                 for(int i = n-1; i>=0; --i)
  12.                 {
  13.                         if(buf[i]<0 || buf[i]>127)
  14.                         {
  15.                                 count++;
  16.                         }
  17.                         else
  18.                         {
  19.                                 break;
  20.                         }
  21.                 }
  22.                 if(count % 2 == 0)
  23.                 {
  24.                         return new String(buf, 0, n);
  25.                 }
  26.                
  27.                 return new String(buf, 0, n-1);
  28.         }
复制代码
回复 使用道具 举报

哦,原来这样就可以了,谢谢大神
回复 使用道具 举报
谢谢各位大神的帮助,万分感谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马