黑马程序员技术交流社区

标题: 一道编程题 [打印本页]

作者: 东大小宇哥    时间: 2015-5-18 20:49
标题: 一道编程题
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是
要保证汉字不被截半个,如"我 ABC"4,应该截为"我 AB",输入"我 ABC 汉 DEF",6,应该输出为"我
ABC"而不是"我 ABC+汉的半个"。
作者: shentan000    时间: 2015-5-18 21:20
我顶~~~~~
作者: 狙神自傲    时间: 2015-5-18 21:34

import java.io.UnsupportedEncodingException;

public class Str {
        public static void main(String args[])throws UnsupportedEncodingException
        {
                String s="我 ABC 汉 DEF";
                System.out.println(Panduan(s,6));
        }
public static String Panduan(String s,int a) throws UnsupportedEncodingException
        {
        byte[] b=s.getBytes("GBK");
        byte[] buf=new byte[a];
        for (int i=0;i<a;i++)
                buf [i]=b [i];
                        String ss=new String(buf,"GBK");
                        if(s.contains(ss))
                                return ss;
                        else
                        {
                                byte[] buff=new byte[a-1];
                                for (int i=0;i<a-1;i++)
                                        {buff[i]=b[i];}
                                                String s2=new String(buff,"GBK");
                                       
                                                        return s2;
                        }
        }
}
作者: 0416朱珅平    时间: 2015-5-18 22:12
今天我们刚学的,可以忘了  楼上的真大神
作者: 南方小道士    时间: 2015-5-18 22:29
楼上已经回答了
作者: zhangjnia    时间: 2015-5-18 22:51
不错,学习了
作者: 紫夜流星    时间: 2015-5-19 00:45
学习学习
作者: chencanhui    时间: 2015-5-19 02:09
学习学习

作者: 灯火通明    时间: 2015-5-19 06:41
学习了。
作者: leeshaodong    时间: 2015-5-20 22:19
这是哪里的课程?学什么的? String?
作者: 13699266500    时间: 2015-5-20 22:20
我今天刚学!
作者: 开弓没有回头箭    时间: 2015-5-20 22:39
又学到了一点
作者: as604049322    时间: 2015-5-20 23:57
本帖最后由 as604049322 于 2015-5-29 18:52 编辑

感觉楼上的方法好垃圾,一点算法效率都没有。。
其次楼主一定要说清楚是什么编码表,在unicode编码中英文汉字都是两字节,而最前面有标识符。如果只是针对GBK的编码,这题就很简单,代码如下:今天再次看自己的代码感觉还是垃圾,于是修改成这样,修改后的代码(最下面有修改前的代码):

  1. package juni.test;

  2. import java.util.Scanner;

  3. class Test
  4. {
  5.     public static void main(String[] args) throws Exception
  6.     {
  7.         /*编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是
  8. 要保证汉字不被截半个,如"我 ABC"4,应该截为"我 AB",输入"我 ABC 汉 DEF",6,应该输出为"我
  9. ABC"而不是"我 ABC+汉的半个"。*/
  10.         Scanner sc=new Scanner(System.in);
  11.         while(true){
  12.             System.out.println("请输入要转换的字符序列:");
  13.             String str=sc.nextLine();
  14.             if(str.equals("over"))
  15.                     break;
  16.             System.out.println("请输入要截取的个数:");
  17.             int len=Integer.parseInt(sc.nextLine());
  18.             String result=subStringForm(str,len);

  19.             System.out.println(result);
  20.         }
  21.     }

  22.     public static String subStringForm(String str,int len) throws Exception{
  23.         byte[] bytes=str.getBytes("gbk");
  24.         if(len>bytes.length)
  25.                 len=bytes.length;

  26.         int count=0;
  27.         for(int i=len-1;i>=0;i--){
  28.             if(bytes[i]>0)
  29.                 break;
  30.             count++;
  31.         }
  32.         if(count%2==0)
  33.             return new String(bytes,0,len,"gbk");
  34.         return new String(bytes,0,len-1,"gbk");

  35.     }
  36. }


复制代码


修改前:

  1. public static String subStringForm(String str,int len) throws Exception{
  2.         byte[] bytes=str.getBytes("gbk");
  3.         if(bytes[len-1]>0)
  4.             return new String(bytes,0,len,"gbk");
  5.         int count=0;
  6.         for(int i=0;i<len;i++){
  7.             if(bytes[i]<0)
  8.                 count++;
  9.         }
  10.         if(count%2==0)
  11.             return new String(bytes,0,len,"gbk");
  12.         return new String(bytes,0,len-1,"gbk");

  13.     }

复制代码


作者: hellotaomi    时间: 2015-5-29 17:28
as604049322 发表于 2015-5-20 23:57
感觉楼上的方法好垃圾,一点算法效率都没有。。
其次楼主一定要说清楚是什么编码表,在unicode编码中英文汉 ...

看不懂后面的代码,百度了一下: 思路:
判断最后一个被截取的字节是不是负数。
如果是负数,继续往前判断,连续的负数的个数。
如果是偶数,说明没有半个中文。不用舍弃。
如果是奇数,说明有半个中文出现,舍弃最后一个字节。

可是还是不太懂,难道中文字的码值比0的码值小吗?求大神解释下!
作者: 志行    时间: 2015-5-29 17:36
................我去  这貌似和我的基础测试一样,不过 中间的字不一样而已~~~~~
作者: 志行    时间: 2015-5-29 17:38
package com.itheima ;
/**
10、编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表),例如:从“HM程序员”中截取2个字节是“HM”,截取4个则是“HM程”,截取3个字节也要是"HM"而不要出现半个中文
*/
public class Test10 {

    public static void main(String[] args) {
            
            //调用函数,输出测试
            System.out.println(mySubstring("HM程序员",2));
            System.out.println(mySubstring("HM程序员",4));
            System.out.println(mySubstring("HM程序员",3));
    }
   
    //定义一个方法,接收原始字符串和需要截取的字节数,返回截取到的字符串
    public static String mySubstring(String str,int count) {
            
            //定义一个byte[]
            byte[] bytes = null;
            //获取字节数组时,指定为按GBK编码获取,需要处理不支持GBK的机子上的异常
            try {
                    bytes = str.getBytes("GBK");
            } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
            }
            //判断输入的字节个数是不是正整数
            if(count<0)
                    throw new RuntimeException("获取字节个数为负数,错误!");
            //判断输入的字节个数是否大于原始字符串长度,是,则输出原字符串
            else if(count>str.length())
                    return str;
            //判断输入的字节个数是不是奇数
            else if(count>0 && count%2==1) {
                    //是奇数,才判断要获取的最后一个字节是不是汉字的一半,通过负数判断
                    if((byte)bytes[count-1]<0){
                            //是汉字一半,就减一个字节
                            count--;
                    }
            }
            
            //获取要得到的新字节数组
            byte[] newbytes=new byte[count];
            for(int x=0;x<count;x++){
                    newbytes[x]=bytes[x];
            }
            
            //将新字节数组转回字符串,并返回
            String newStr=new String(newbytes);
            return newStr;
    }

}         
作者: as604049322    时间: 2015-5-29 19:00
hellotaomi 发表于 2015-5-29 17:28
看不懂后面的代码,百度了一下: 思路:
判断最后一个被截取的字节是不是负数。
如果是负数,继续往前判 ...

ACSII码是最高位为0,低7位存储数据。GBK为了兼容ACSII码,存储汉字必然要最高位为1,而最高位为1的数就是负数。。。
作者: ZYZQ    时间: 2015-5-29 19:05
Mark,字符编码相关
作者: hzw@ql    时间: 2015-5-29 20:07
学习了。。
作者: hellotaomi    时间: 2015-5-30 11:32
as604049322 发表于 2015-5-29 19:00
ACSII码是最高位为0,低7位存储数据。GBK为了兼容ACSII码,存储汉字必然要最高位为1,而最高位为1的数就 ...

哦 酱紫啊 ,我懂啦,谢谢~




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