黑马程序员技术交流社区
标题:
一道关于汉字的截断题
[打印本页]
作者:
wx999
时间:
2015-5-9 14:58
标题:
一道关于汉字的截断题
本帖最后由 wx999 于 2015-5-9 22:59 编辑
题目:编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个。如输入:"我ABC"和4,应该截取“我AB”,输入“我ABC汉DEF”和6,应该输出“我ABC”,而不是“我ABC+汉的半个”。
代码
import java.util.*;
class Test
{
public static void main(String[] args)
{
jieduan();
}
public static void jieduan()
{
Scanner in = new Scanner(System.in);
System.out.println("请输入字符串:");
String str = in.next();
System.out.println("请输入截断位置:");
int num = in.nextInt();
byte[] b = str.getBytes();
int len = b.length;
if(len>num)
{
if(b[num]>0)
{
String s = new String(b,0,num);
System.out.println(s);
}
else
{
String s = new String(b,0,--num);
System.out.println(s);
}
}
else
System.out.println("输入错误!");
}
}
复制代码
虽然满足了题目的示例,但如果输入"String是一种基本的数据类型",截断位置是奇数是正确的,如果是偶数就会有错误,如输入16,显示结果是 String是一种基? 。
这个程序该怎么改,或者还有其他办法来完成这题吗?求教各位大神
作者:
396460221
时间:
2015-5-9 15:45
package basetest;
import java.io.*;
/*编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表),例如:从“HM程序员”中
* 截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是“HM”而不要出现半个中文。
* 思路:
* 1.将指定的字符串变成字节数组
* 2.通过判断指定字节数组的长度来返回相应的字符串
* 3.截取字节生成新字符串和源字符串上的相同字符比较,一样说明没有半个汉字,返回字符串,不一样说明有
* 半个汉字,返回-1后的字符串。
*/
public class Test10 {
public static void main(String[] args) {
String s ="heima程序员很牛逼!";//源字符串
System.out.println(getString(s,9));
}
public static String getString(String str,int num) {
//将字符串转换成字节数组时,需要处理不支持GBK机器上的异常
byte[] buf =null;
try{
buf =str.getBytes("GBK");//将指定字符串变成字节数组
}
catch(IOException e){
e.printStackTrace();//捕获异常
}
if(num<0) //指定获取的字节数如果小于0,抛Runtime异常
throw new RuntimeException("获取字节个数为负数,错误");
else if (num>str.length())//截取字节数大于原字符串长度,返回原字符串
return str;
else {
String s = new String(buf,0,num);//截取字节数组转换成字符串
int length = s.length();
if(s.charAt(length-1)!=str.charAt(length-1)){//转换后的字符串和原字符串相同位置的字符比较,相同返回原串,
//不相同说明截到半个汉字,返回从0到截取数字-1位置处的字节转换成字符串。
s = s.substring(0,length-1);
return s;
}
return s;
}
}
}
复制代码
作者:
showdy
时间:
2015-5-9 19:03
public static void main(String[] args) throws Exception {
String str = "HM程序员cdd深圳校区";
int num = trimGBK(str.getBytes("GBK"), 5);
System.out.println(str.substring(0, num));
}
public static int trimGBK(byte[] buf, int n) {
int num = 0;
Boolean bChineseFirstHalf = false;
for (int i = 0; i < n; i++) {
if (buf[i] < 0 && !bChineseFirstHalf) {
bChineseFirstHalf = true;
} else {
num++;
bChineseFirstHalf = false;
}
}
return num;
}
复制代码
作者:
szw727
时间:
2015-5-9 19:54
如果截取到汉字的一半,那么这半个字的Ascii码肯定不再 0-127,所以可以判断这半个字的 第 n-1这个字符的ASCII码,如果这个值在 0-127, 那么这个n-1就要着,直接截取就可以了
如果这个值不再0-127, 那么从这个字符为起点向前变量, 到遇到一个0-127的结束,看看变量中有几个不再0-127的数, 如果是偶是这个n-1就保存,如果是奇数,这个n-1就是半个字符,舍弃掉
public static String subStr(String str, int n)
{
if(n<1)
{
return null;
}
byte[] buf = str.getBytes();
byte by1 = buf[n-1];
int count = 0;
for(int i = n-1; i>=0; --i)
{
if(buf[i]<0 || buf[i]>127)
{
count++;
}
else
{
break;
}
}
if(count % 2 == 0)
{
return new String(buf, 0, n);
}
return new String(buf, 0, n-1);
}
复制代码
作者:
wx999
时间:
2015-5-9 22:54
396460221 发表于 2015-5-9 15:45
哦,原来这样就可以了,谢谢大神
作者:
wx999
时间:
2015-5-9 22:59
谢谢各位大神的帮助,万分感谢
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2