前几天面试的一家小公司,公司不大,只有五六十个人,公司不大,但要求特别严谨,做对了不行,还要求考虑所有可能的情况。给了一道编程题和一大堆图形推理题,全是逻辑题。编程题两个小时之内做完,我做了一个多小时,结果是做出来了,但她说我考虑的点还不够全。现题目和改进后的代码分享如下:
题目
请您用java语言实现两个函数encode()和decode(),分别实现对字符串的变换和复原.变换函数encode()顺序考察已知字符串的字符,按以下规则逐组生成新字符串:
(1)若已知字符串的当前字符不是大于0的数字字符,则复制该字符于新字符串中;
(2)若已知字符串的当前字符是一个数字字符,且它之后没有后继字符,则简单地将它复制到新字符串中;
(3)若已知字符串的当前字符是一个大于0的数字字符,并且还有后继字符,设该数字字符的面值为n,则将它的后继字符(包括后继字符是一个数字字符)重复复制n+1次到新字符串中;
(4)以上述一次变换为一组,在不同组之间另插入一个下划线'_'用于分隔;
(5)若已知字符串中包含有下划线'_',则变换为 ”\UL” 。
复原函数decode()做变换函数encode()的相反的工作.按照上述规则逆运算,变回原来的字符串。
例如:encode()函数对字符串24ab_2t2的变换结果为 444_aaaaa_a_b_\UL_ttt_t_2
说明:
题目的条件一有歧义,一种理解是:当前字符是一个小于等于0的数字字符;第二种理解是当前字符是一个除了1-9的任意字符。
我是基于第二种意思理解进行的解答。
假设字符为String str, n = str.length(); 当前字符为c = str[i]
一、进行encode()判断的条件:
(1)、c是等于0的数字 复制该字符
c是一般字符,且不为”_” 复制该字符
以上两个条件等同于:c是一个除了1-9,除了”_”的任意字符
(5)、c是一般字符,且为”_” 转换为”\Ul”
(2)、c是数字,且i=n-1 复制该字符
(3)、c是数字,且i<n-1,且c>0 复制(k+1)次后面的一个字符
以上四个条件拆分如下:
c == 0 i==n-1 复制该字符
i!=n-1 复制该字符
c是1-9的数字, 且i=n-1 复制该字符
且i<n-1 复制(k+1)次后面的一个字符
c是一般字符,且为”_” 转换为”\Ul”
c是一般字符,且不为”_” 转换为”\Ul”
再化为如下判断条件:
c是1-9的数字, 且i<n-1 复制(k+1)次后面的一个字符
c除1-9,且为”_” 转换为”\Ul”
其余 复制该字符
(4)、每个字符译码结束后加一个下划线”_”
二、进行decode()判断的条件:
思路:
根据规则4,用先将str用str.split("_");分成n个String数组strs[].
n = strs.lenth k = strs[i].length()
由encode()得到的译码如下:
c是1-9的数字, 且i<n-1 复制(k+1)次后面的一个字符 多个字符
c除1-9,且为”_” 转换为”\Ul” 多个字符
其余 复制该字符 一个字符
判断条件为:
A、k==1, 将该字符原样复原
B、k>1, strs[i] == ”\Ul”, 转换为”_”
strs[i] != ”\Ul”, 转换为k(k = strs[i].length()-1)
代码:
/** * 联系电话: * 时间: * @author SmilingSunrise * */ public class EncodeAndDecode { /** * 译码 * * @param str * 要译码的字符串 * @return 译码后的字符串 */ public String encode(String str) throws StringLenException{ StringBuilder sb = new StringBuilder(); if(null == str) { throw new StringLenException("字符串末初始化!"); } int n = str.length(); if(n <=0) { throw new StringLenException("字符串不能为空!"); } char c = 0; int k = 0; for (int i = 0; i < n; i++) { // 获得当前字符 c = str.charAt(i); if (c >= '1' && c <= '9' && i != n-1) { // c是1-9的数字, 且i<n-1 复制(k+1)次后面的一个字符 k = c -'0' + 1; for(int j=0; j<k; j++) { sb.append(str.charAt(i+1)); } } else if (c == '_') { // c除1-9,且为”_” 转换为”\Ul” sb.append("\\UL"); }else{ //其余 复制该字符 sb.append(c); } sb.append("_"); } return sb.deleteCharAt(sb.length()-1).toString(); } /** * 解码 * * @param str * 要解码的字符串 * @return 解码后的字符串 */ public String decode(String str) { StringBuilder sb = new StringBuilder(); if(null == str) { throw new StringLenException("字符串末初始化!"); } if(sb.length() <=0) { throw new StringLenException("字符串不能为空!"); } String strs[] = str.split("_"); char c = 0; int k = 0; int n = strs.length; if(n == 1) { sb.append(str); } else { for(int i=0; i<n; i++) { k = strs[i].length(); c = strs[i].charAt(0); if(1 ==k) { // k==1, 将该字符原样复原 sb.append(c); } else { // k>1, if(strs[i].equals("\\UL")) {//strs[i] == ”\Ul”, 转换为”_” sb.append("_"); } else { // strs[i] != ”\Ul”, 转换为k(k = strs[i].length()-1) sb.append(k-1); } } } } return sb.toString(); } /** * @param args */ public static void main(String[] args) { String s = "24ab_2t2"; // String s = "04ab_2t2"; // String s = "1a0b_2t2"; // String s = "aaab_2t2"; // String s = "24ab_2335t2"; // String s = "240ab_"; /*EncodeAndDecode encode = new EncodeAndDecode(); String s1 = encode.encode(s); System.out.println("encode:" + s1); String s2 = encode.decode(s1); System.out.println("decode:" + s2); */ } }
public class StringLenException extends RuntimeException { public StringLenException() { super(); } public StringLenException(String message) { super(message); } }
测试例子:
Encode函数输入以下用例:
24ab_2t2
444_aaaaa_a_b_\UL_ttt_t_2
04ab_2t2
0_aaaaa_a_b_\UL_ttt_t_2
1a0b_2t2
aa_a_0_b_\UL_ttt_t_2
aaab_2t2
a_a_a_b_\UL_ttt_t_2
24ab_2335t2
444_aaaaa_a_b_\UL_333_3333_5555_tttttt_t_2
240ab_
444_00000_0_a_b_\UL