黑马程序员技术交流社区

标题: 编程题:截取有汉字的字符串的函数 [打印本页]

作者: 孙辉辉    时间: 2012-12-16 10:49
标题: 编程题:截取有汉字的字符串的函数
题目:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。
只是不知道如果判断一个是不是汉字,求思路。另外如果要截取的为1,是不是就输出为空呢?
作者: Kevin123    时间: 2012-12-16 14:23
给楼主点思路,先字符串转化为数组,然后统计截取长度中汉字所占的字节数,一个汉字占两个字节,通过统计值奇偶数来判断是否截半。
byte st[]=str.getBytes();
if(st[i] < 0)        //st[i]所存字节为汉字,其值小于零,count值加一。
++count;
应该很明了了,楼主具体实现吧
作者: 王晨    时间: 2012-12-16 16:48
Java判断一个字符串是否有中文是利用Unicode编码来判断,因为中文的编码区间为:0x4e00--0x9fbb,不过通用区间来判断中文也不非常精确,因为有些中文的标点符号利用区间判断会得到错误的结果。而且利用区间判断中文效率也并不高,例如;str.substring(i, i + 1).matches("[\\u4e00-\\u9fbb]+"),就需要遍历整个字符串,如果字符串太长效率非常低,而且判断标点还会错误。
我再网上看到的这个代码,感觉效率挺高的.你可以试试看……
  1. package com.zakisoft.ch;   
  2.   
  3. public class IsChineseOrNot {   
  4.   
  5.     // GENERAL_PUNCTUATION 判断中文的“号   
  6.     // CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号   
  7.     // HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号   
  8.     private static final boolean isChinese(char c) {   
  9.         Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);   
  10.         if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS   
  11.                 || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS   
  12.                 || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A   
  13.                 || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION   
  14.                 || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION   
  15.                 || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {   
  16.             return true;   
  17.         }   
  18.         return false;   
  19.     }   
  20.   
  21.     public static final boolean isChinese(String strName) {   
  22.         char[] ch = strName.toCharArray();   
  23.         for (int i = 0; i < ch.length; i++) {   
  24.             char c = ch[i];   
  25.             if (isChinese(c)) {   
  26.                 return true;   
  27.             }   
  28.         }   
  29.         return false;   
  30.     }   
  31.   
  32.     public static void main(String[] args) {   
  33.         System.out.println(isChinese("き"));   
  34.         System.out.println(isChinese("test,.?!%^&*(){}[]"));   
  35.         System.out.println(isChinese("测试"));   
  36.         System.out.println(isChinese("“测试”,。?!%……&*()——{}【】”"));   
  37.     }   
  38.   
  39.     public static final boolean isChineseCharacter(String chineseStr) {   
  40.         char[] charArray = chineseStr.toCharArray();   
  41.         for (int i = 0; i < charArray.length; i++) {   
  42.             if ((charArray[i] >= 0x4e00) && (charArray[i] <= 0x9fbb)) {   
  43.                 return true;   
  44.             }   
  45.         }   
  46.         return false;   
  47.     }   
  48.   
  49.     /**  
  50.      * @deprecated; 弃用。和方法isChineseCharacter比效率太低。  
  51.      * */  
  52.     public static final boolean isChineseCharacter_f2() {   
  53.         String str = "!?";   
  54.         for (int i = 0; i < str.length(); i++) {   
  55.             if (str.substring(i, i + 1).matches("[\\u4e00-\\u9fbb]+")) {   
  56.                 return true;   
  57.             }   
  58.         }   
  59.         return false;   
  60.     }   
  61. }  
复制代码
我运行了一下,可以判断是否为字符,你试试能不能用!
作者: 孙辉辉    时间: 2012-12-16 22:09
根据以上思路,和之后网上的一些资料,自己写了一个
  1. public static String splitString(String str,int byteLength) {
  2.                 //如果字符串为空或者长度为0,则返回原串
  3.                 if(str==null||str.length()==0)
  4.                         return str;
  5.                 //定义字节数组来存经GBK转换后的 byte序列
  6.                 byte[] strByte = null;
  7.                 try {
  8.                         strByte = str.getBytes("GBK");
  9.                 } catch (UnsupportedEncodingException e) {
  10.                         // TODO Auto-generated catch block
  11.                         e.printStackTrace();
  12.                 }
  13.                 //定义存储要截取段汉字字节数,初始化为0
  14.                 int wordCount = 0;
  15.                 //统计截取段所含有的汉字字节数
  16.                 for(int i = 0;i <byteLength;i++){
  17.                         int num = strByte[i];//num小于零是汉字,汉字通过strByte方法取出之后是小于零的
  18.                         // 如果是汉字(负),则统计截取字符串中的汉字所占字节数
  19.                         if(num < 0){
  20.                                 wordCount++;
  21.                         }
  22.                 }
  23.                 //如果汉字占奇数个字节数,则说明要截取了半个汉字,应当做是一个来处理
  24.                 if(wordCount % 2 == 1)
  25.                         wordCount = wordCount + 1;       
  26.                 //subString 的截取长度应该为要截取的字节数-其中包括的汉字个数(wordCount/2)
  27.                 return str.substring(0, (byteLength-(wordCount/2)));
  28.         }
  29.         public static void main(String[] args) {
  30.                 //定义一个字符串
  31.                 String str = "我ABC汉DEF";
  32.                 System.out.println(splitString(str,7));
  33.         }
复制代码

作者: 高焕杰    时间: 2012-12-16 23:38
这样可能更简单:

public class Test
{
        /**
         * @param str 输入的字符串
         * @param length 欲截取的字节数
         * @param flag 旗标
         */
public void test(String str,int length){
        String newStr=str.substring(0, length);
        String regEx = "[\\u4e00-\\u9fa5]";      
        Pattern p = Pattern.compile(regEx);      
        Matcher m = p.matcher(newStr);
        int count=0;
        while (m.find()) {      
             for (int i = 0; i <= m.groupCount(); i++) {      
                   count = count + 1;      
               }      
           }      
    if (count==0) {//所截字符串中没有汉字。
                System.out.println(newStr);
        }
    else{//所截字符串中含有汉字。
            System.out.println(newStr.substring(0,(length-count)));
    }
}
public static void main(String[] args)
{
        new Test().test("我ABC汉DEF", 6);//结果为:我ABC
       
}
}




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