黑马程序员技术交流社区
标题:
截取字符串子串,我想了几个小时
[打印本页]
作者:
吴光新
时间:
2013-7-23 23:14
标题:
截取字符串子串,我想了几个小时
本帖最后由 Jiewin 于 2013-7-23 23:21 编辑
有道题,想了几个小时,才做好!!!!还有没有更好的办法呢?
编写一个截取字符串的函数,输入为一个字符串和字节数, 输出为按字节截取的字符串,但要保证汉字不被截取半个,
如"我ABC",4,应该截取"我AB",输入"我ABC汉DEF",6, 应该输出"我ABC",而不是"我ABC+汉的半个"。
public class getStrDemo {
public static void main(String[] args){
String str = "我ABC汉DEF";
System.out.println(getStr(str, 6));
}
public static String getStr(String str, int num) {
byte[] index = str.getBytes();
//len 是记录汉字的字节出现次数
//endIndex 就是截取字符串时的末尾索引。
int cnlen = 0;
int endIndex = 0;
for (int x=0; x<num; x++){
if (index[x]<0)
cnlen++;
if(cnlen %2==0)
endIndex++;
}
return str.substring(0, endIndex);
}
}
复制代码
作者:
董延京
时间:
2013-7-23 23:54
很厉害的想法,一个汉字被分成了两个byte,然后判断每一个byte,是一个负数值,这个我还真是不知道。
但是,这个也有缺陷,汉字在GBK编码的情况下,确实是两个byte表示,如果是UTF-8就会使三个byte,那么就会出现问题,我把这个程序考下来,然后保存为utf-8的格式文件,编译运行后就错误了。只截取了"我"。
下面是我的做法:
public class Test10 {
/**
* 编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。
* 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,
* 6,应该输出为“我ABC”而不是“我ABC+汉的半个”.
*
* 思路:从前往后取字符串的每一个字符,如果是中文,则按两个字符计算。
*
*/
public static void main(String[] args) {
System.out.println(cut("我ABC", 4));//我AB
System.out.println(cut("我ABC汉DEF", 6));//我ABC
System.out.println(cut("不能直接去一半",7));//不能直
//截取长度刚好等于字符串长度。
System.out.println(cut("abcd", 4));//abcd
//截取长度大于字符串长度。
System.out.println(cut("nice", 100));//nice
}
//截取方法,content为字符串的内容,meger为截取长度。
public static String cut(String content, int meger) {
//定义一个Stringbuffer,用来存放合并字符串截取的内容。
StringBuffer stb = new StringBuffer();
//将需要截取的字符串拆分为字符数组。
char[] cs = content.toCharArray();
//定义一个标志位flag,它用来判断当前截取长度,不能大于给定的要求长度meger。
int flag = 0;
//定义一个判断量i,可以记录当前位置上字符的值,同时因为可能给定的长度要大于字符串长度,防止抛出下标越界异常。
int i = 0;
//循环,只要标志位的长度不长于给定截取长度,则继续截取。
while (flag < meger) {
//判断当前字符是否为中文。
if (judgeChar(cs[i])) {
//是,那么标志位,需要增加2,一个中文字符,相当于两个字符。
flag += 2;
} else {
//否,只加1.
flag += 1;
}
//标志位此时只要依然在给点范围内。则将此就将这个字符添加到StringBuffer后边。
if (flag <= meger) {
stb.append(cs[i]);
}
//++i,使i指向字符数组的下一下标
//如果i的长度,已经指向字符数组的末尾,那么给定长度必然大于字符串长度。循环结束。
if (++i >= cs.length)
break;
}
return stb.toString();
}
//判断字符是否为中文字符的方法。
public static boolean judgeChar(char c) {
if ((c >= 0x4e00) && (c <= 0x9fbb)) {
return true;
}
return false;
}
}
复制代码
作者:
吴光新
时间:
2013-7-24 00:36
董延京 发表于 2013-7-23 23:54
很厉害的想法,一个汉字被分成了两个byte,然后判断每一个byte,是一个负数值,这个我还真是不知道。
但是 ...
恩,编码的问题我有考虑过的,也做过实验,因为只是交作业,没有考虑别的因素,
我看了很多网站都是用的UTF-8的,解决这个问题也很简单,一般默认的是GBK,或者指定了UTF-8,有几种方法解决:
1、在程序内部做两种编码的处理方式,但作为程序员就没必要这样做
2、%其实就是针对GBK的2字节,UTF-8的3个字节就可以%3,下面在做相应的修改就行了
作者:
☆今☆
时间:
2013-7-24 20:55
public class Test10{
public static void main(String[] args)
{
String str="我ABC汉DEF";
int length = 6;
System.out.println(subString(str,length));
}
public static String subString(String str,int length){//用于字符串截取的方法
byte[] bytes=str.getBytes(); //将字符串按字节存储
int count1 = 0; //用于记录判定是否包含整个汉字
int count2 = 0; //用于记录length长度中有几个汉字
int strLength=length; //保存length
if(str==null||length > bytes.length){ //判定字符串是否为空,或字符串字节长度是否小于截取长度
return str; //若为真直接返回字符串.
}
else{
for (int i = 0;length > 0;i++) { //用截取长度判断字符串中字符的个数
if(bytes[i] < 0){ //bytes[i]小于0表示是汉字
count1++; //若有汉字则记录
if(count1 == 2){ //表示length中包含整个汉字
count1 = 0; //清零,进行再次记录
count2++; //length中包含汉字的个数+1
}
}
length--; //截取长度减一
if(length == 0){ //若截取长度为0
if (count1==1) { //但汉字是不完整的
return str.substring(0,strLength-count2-1);//因为在字符串中汉字为1个字符,但占2个字节
} //返回长度为减去汉字的个数,-1是减掉最后一个不完整的汉字
}
}
return str.substring(0,strLength-count2); //若最后不是不完整的汉字,则直接减去汉字个数
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2