一个关于字符串操作的算法题

最近在网上看到一道关于字符串操作的算法题,不过原题的表述以及给出的数据都有问题.这里我给出修正后的题目:

题目: 设计一个方法 String encode(String str),对字符串str进行如下转换操作为一个新字符串:

         逐个扫描str的每个字符,

         1.若当前字符为'_',则添加"\UL"到新字符串; 否则:

         2.若当前字符表示一大于0的数字N,且该字符不是最后一个字符,则将后继字符添加N+1次到新字符串;否则:

         3.直接添加当前字符到新字符串.

         并且用一个字符'_'将相邻的变换隔开

         并设计一个String decode(String code)方法执行encode的逆操作,即将由encode(str)方法返回的字符串还原为str.

       encode方法的设计没有任何难度,只需要把题目"直译"成程序代码就OK了,有难度的地方在于decode方法.注意到字符串中的字符在encode之后的新字符串中是由'_'分开的,并且原字符串中的每个字符只由这个字符串变换后的字符串以及其后继字符有关,因此我们很容易可以想到先将编码后的字符串按'_'分解成一系列字符串,其中每个字符串对应原字符串的一个字符,然后从后向前一个个求出其所表示的字符.算法的大体想法就是这样,只有一点要注意:类似"4_"这种数字后跟'_'的情形会被编码成一列连续的"_____",应该区分出这种情形并加以处理 .

       其实如果对压缩算法有所了解的话,很容易看出这个题目其实是行程编码( Run-Length Encoding )的一个变形.

下面给出本题的代码:

java 代码
  1. /**  
  2. *author: Eastsun  
  3. *version: 1.0 2007/8/1  
  4. */   
  5. import  java.util.Scanner;   
  6. public   class  StringCode{   
  7.      public   static   void  main(String[] args){   
  8.         Scanner s = new  Scanner(System.in);   
  9.          while ( true ){   
  10.             String text =s.next();   
  11.              if ( "exit" .equalsIgnoreCase(text))  break ;   
  12.             String code =encode(text);   
  13.              boolean  flags = true ;        //用于检测decode是否正确工作的标记   
  14.              try {   
  15.                  if (!decode(code).equals(text)) flags = false ;   
  16.             } catch (IllegalStateException e){   
  17.                 flags = false ;   
  18.             }   
  19.              if (flags){   
  20.                 System.out.println( "Code :"  +code);   
  21.             }   
  22.              else {   
  23.                 System.out.println( "Error code :"  +code);   
  24.             }   
  25.         }   
  26.     }   
  27.      private   static   final  String ESC_S =  "\\UL" ;   
  28.      private   static   final   char    ESC_C = '_';   
  29.        
  30.      /**  
  31.     *将编码后的字符串还原为原字符串  
  32.     *@throws IllegalStateException 如果参数str不是一个有效的编码字符串  
  33.     */   
  34.      public   static  String decode(String str) throws  IllegalStateException{   
  35.         StringBuilder sb = new  StringBuilder();   
  36.          char  next = 0xffff ;   
  37.          int  end =str.length(), start;   
  38.          while (end> 0 ){   
  39.              if (next==ESC_C&&str.charAt(end- 1 )==ESC_C){   
  40.                  for (start =end - 1 ;start> 0 &&str.charAt(start- 1 )==ESC_C;start--);   
  41.                  if (start!= 0 ) start ++;   
  42.             }   
  43.              else {   
  44.                 start =str.lastIndexOf(ESC_C,end - 1 ) + 1 ;   
  45.             }   
  46.                
  47.             String code =str.substring(start,end);   
  48.                
  49.              if (code.equals(ESC_S)){   
  50.                 next = ESC_C;   
  51.             }   
  52.              else   if (end-start== 1 ){   
  53.                 next = code.charAt( 0 );   
  54.             }   
  55.              else {   
  56.                  for ( int  index = 0 ;index
  57.                      if (code.charAt(index)!= next)  throw   new  IllegalStateException( "Illegal code: [" +start+ "," +end+ "]" );   
  58.                 next =( char )(' 0 '+end-start- 1 );   
  59.             }   
  60.             sb.insert( 0 ,next);   
  61.             end =start - 1 ;   
  62.         }   
  63.          return  sb.toString();   
  64.     }   
  65.        
  66.      /**  
  67.     * 将str编码为新的字符串  
  68.     */   
  69.      public   static  String encode(String str){   
  70.         StringBuilder sb = new  StringBuilder();   
  71.          for ( int  index = 0 ;index
  72.              char  c =str.charAt(index);   
  73.                
  74.              if (c==ESC_C){   
  75.                 sb.append(ESC_S);   
  76.             }   
  77.              else   if (c>' 0 '&&c<=' 9 '&&index+ 1
  78.                  char  next =str.charAt(index+ 1 );   
  79.                  for ( int  count =c-' 0 ';count>= 0 ;count--)    
  80.                     sb.append(next);   
  81.             }   
  82.              else {   
  83.                 sb.append(c);   
  84.             }   
  85.                
  86.              if (index+ 1
  87.         }   
  88.          return  sb.toString();   
  89.     }   
  90. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值