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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴光新 黑马帝   /  2013-7-23 23:14  /  1353 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 Jiewin 于 2013-7-23 23:21 编辑

有道题,想了几个小时,才做好!!!!还有没有更好的办法呢?

编写一个截取字符串的函数,输入为一个字符串和字节数, 输出为按字节截取的字符串,但要保证汉字不被截取半个,
如"我ABC",4,应该截取"我AB",输入"我ABC汉DEF",6, 应该输出"我ABC",而不是"我ABC+汉的半个"。

  1. public class getStrDemo {
  2.         public static void main(String[] args){
  3.                 String str = "我ABC汉DEF";
  4.                 System.out.println(getStr(str, 6));
  5.         }
  6.         public static String getStr(String str, int num) {
  7.                 byte[] index = str.getBytes();
  8.   
  9.                 //len 是记录汉字的字节出现次数
  10.                 //endIndex 就是截取字符串时的末尾索引。
  11.                 int cnlen = 0;
  12.                 int endIndex = 0;
  13.                 for (int x=0; x<num; x++){
  14.                         if (index[x]<0)
  15.                                 cnlen++;
  16.                          if(cnlen %2==0)
  17.                                 endIndex++;
  18.                 }
  19.                 return str.substring(0, endIndex);
  20.          }
  21. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
特殊服务 + 1

查看全部评分

3 个回复

倒序浏览
很厉害的想法,一个汉字被分成了两个byte,然后判断每一个byte,是一个负数值,这个我还真是不知道。
但是,这个也有缺陷,汉字在GBK编码的情况下,确实是两个byte表示,如果是UTF-8就会使三个byte,那么就会出现问题,我把这个程序考下来,然后保存为utf-8的格式文件,编译运行后就错误了。只截取了"我"。
下面是我的做法:

  1. public class Test10 {

  2.         /**
  3.          * 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。
  4.          * 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,
  5.          * 6,应该输出为“我ABC”而不是“我ABC+汉的半个”.
  6.          *
  7.          * 思路:从前往后取字符串的每一个字符,如果是中文,则按两个字符计算。
  8.          *
  9.          */
  10.         public static void main(String[] args) {
  11.                
  12.                 System.out.println(cut("我ABC", 4));//我AB
  13.                
  14.                 System.out.println(cut("我ABC汉DEF", 6));//我ABC
  15.                
  16.                 System.out.println(cut("不能直接去一半",7));//不能直
  17.                
  18.                 //截取长度刚好等于字符串长度。
  19.                 System.out.println(cut("abcd", 4));//abcd
  20.                 //截取长度大于字符串长度。
  21.                 System.out.println(cut("nice", 100));//nice
  22.         }

  23.         //截取方法,content为字符串的内容,meger为截取长度。
  24.         public static String cut(String content, int meger) {
  25.                 //定义一个Stringbuffer,用来存放合并字符串截取的内容。
  26.                 StringBuffer stb = new StringBuffer();
  27.                 //将需要截取的字符串拆分为字符数组。
  28.                 char[] cs = content.toCharArray();
  29.                 //定义一个标志位flag,它用来判断当前截取长度,不能大于给定的要求长度meger。
  30.                 int flag = 0;
  31.                 //定义一个判断量i,可以记录当前位置上字符的值,同时因为可能给定的长度要大于字符串长度,防止抛出下标越界异常。
  32.                 int i = 0;
  33.                
  34.                 //循环,只要标志位的长度不长于给定截取长度,则继续截取。
  35.                 while (flag < meger) {
  36.                         //判断当前字符是否为中文。
  37.                         if (judgeChar(cs[i])) {
  38.                                 //是,那么标志位,需要增加2,一个中文字符,相当于两个字符。
  39.                                 flag += 2;
  40.                         } else {
  41.                                 //否,只加1.
  42.                                 flag += 1;
  43.                         }

  44.                         //标志位此时只要依然在给点范围内。则将此就将这个字符添加到StringBuffer后边。
  45.                         if (flag <= meger) {
  46.                                 stb.append(cs[i]);
  47.                         }

  48.                         //++i,使i指向字符数组的下一下标
  49.                         //如果i的长度,已经指向字符数组的末尾,那么给定长度必然大于字符串长度。循环结束。
  50.                         if (++i >= cs.length)
  51.                                 break;

  52.                 }

  53.                 return stb.toString();
  54.         }

  55.         //判断字符是否为中文字符的方法。
  56.         public static boolean judgeChar(char c) {
  57.                 if ((c >= 0x4e00) && (c <= 0x9fbb)) {
  58.                         return true;
  59.                 }
  60.                 return false;
  61.         }

  62. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
特殊服务 + 1

查看全部评分

回复 使用道具 举报
董延京 发表于 2013-7-23 23:54
很厉害的想法,一个汉字被分成了两个byte,然后判断每一个byte,是一个负数值,这个我还真是不知道。
但是 ...

恩,编码的问题我有考虑过的,也做过实验,因为只是交作业,没有考虑别的因素,

我看了很多网站都是用的UTF-8的,解决这个问题也很简单,一般默认的是GBK,或者指定了UTF-8,有几种方法解决:
1、在程序内部做两种编码的处理方式,但作为程序员就没必要这样做
2、%其实就是针对GBK的2字节,UTF-8的3个字节就可以%3,下面在做相应的修改就行了
回复 使用道具 举报
  1. public class Test10{
  2.     public static void main(String[] args)
  3.     {
  4.                 String str="我ABC汉DEF";
  5.                 int length = 6;
  6.                 System.out.println(subString(str,length));
  7.     }

  8.         public static String subString(String str,int length){//用于字符串截取的方法
  9.                 byte[] bytes=str.getBytes();     //将字符串按字节存储
  10.                 int count1 = 0;                 //用于记录判定是否包含整个汉字
  11.                 int count2 = 0;                //用于记录length长度中有几个汉字
  12.                 int strLength=length;          //保存length
  13.                 if(str==null||length > bytes.length){  //判定字符串是否为空,或字符串字节长度是否小于截取长度
  14.                         return str;                        //若为真直接返回字符串.
  15.                 }
  16.                 else{
  17.                         for (int i = 0;length > 0;i++) {     //用截取长度判断字符串中字符的个数
  18.                                 if(bytes[i] < 0){              //bytes[i]小于0表示是汉字
  19.                                         count1++;                  //若有汉字则记录        
  20.                                         if(count1 == 2){            //表示length中包含整个汉字
  21.                                                 count1 = 0;             //清零,进行再次记录
  22.                                                 count2++;               //length中包含汉字的个数+1
  23.                                         }
  24.                                 }
  25.                                 length--;                      //截取长度减一
  26.                                 if(length == 0){                //若截取长度为0
  27.                                         if (count1==1) {             //但汉字是不完整的
  28.                                                 return str.substring(0,strLength-count2-1);//因为在字符串中汉字为1个字符,但占2个字节
  29.                                         }                                              //返回长度为减去汉字的个数,-1是减掉最后一个不完整的汉字
  30.                                 }
  31.                         }
  32.                         return str.substring(0,strLength-count2);  //若最后不是不完整的汉字,则直接减去汉字个数
  33.                 }
  34.         }
  35. }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马