一道面试题(encode和decode)

前几天面试的一家小公司,公司不大,只有五六十个人,公司不大,但要求特别严谨,做对了不行,还要求考虑所有可能的情况。给了一道编程题和一大堆图形推理题,全是逻辑题。编程题两个小时之内做完,我做了一个多小时,结果是做出来了,但她说我考虑的点还不够全。现题目和改进后的代码分享如下:

题目

请您用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("_");分成nString数组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

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌尘(MoChen)

爱打赏的人技术成长更开哦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值