解码方法

有一个消息包含A-Z通过以下规则编码:


'A' -> 1

'B' -> 2

...

'Z' -> 26


现在给你一个加密过后的消息,问有几种解码的方式,写一个函数实现。


格式:


输入行第一行输入一个加密后的消息即一个正整数,最后输出可以实现的解码方式的个数。


样例输入


12


样例输出

AB



解题思路如下:

数组num={1,2,3,1,2}。num[1]表示第一个元素1,同理num[i]表示第i个数字。
a[i]表示前i个数字的解码方法。
那么,
a[1]=1;这是很明显的只有一个数字1
a[2]=2;因为前2个数字1,2有两种组合,分别是{1,2},{12}
a[3]=3=a[2]+a[1];因为前3个数组的组合为{1,2,3},{12,3},{1,23}.
a[4]=3=a[3];因为前4个数字的组合为{1,2,3,1},{12,3,1},{1,23,1}。因为31
   超过了题目中设定,只有26个英文字母。
a[5]=6=a[4]+a[3];前5个数字的组合为{1,2,3,1,2},{12,3,1,2},{1,23,1,2}
   {1,2,3,12},{12,3,12},{1,23,12}
从以上的规律可以总结出
如果num[i-1]num[i]>26,那么a[i] = a[i-1],否则a[i] = a[i-1]+a[i-2]


在这里不给出求的解码方法综合的代码,以下给出的是求的具体密码结果的代码


package suanfa;


public class DecodeWays {
	public static final String[] CHARACTERS = new String[] {"\0","A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
			"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

	public static void main(String ... rags) {
		String str = "123121";
		DecodePasswd[] decodePasswd = decodeNumberString(str);
		printDecodeResult(decodePasswd, str);

	}
	
	public static void printDecodeResult(DecodePasswd[] decodePasswd, String str) {
		// 遍历打印所有的解密结果
		for (int i = 0; i < decodePasswd.length; i++) {
			int l = 0;
			if (decodePasswd[i].getAloneDecodePwd() != null) {
				l += decodePasswd[i].getAloneDecodePwd().length;
			}
			if (decodePasswd[i].getUnionDecodePwd() != null) {
				l += decodePasswd[i].getUnionDecodePwd().length;
			}
			System.out.println("数字字符串["+str.substring(0, i + 1) + "]有[" + l + "]种解码方法,解得的密码为:");
			for (int j = 0; decodePasswd[i].getAloneDecodePwd() != null && j < decodePasswd[i].getAloneDecodePwd().length; j++) {
				System.out.println("    " + decodePasswd[i].getAloneDecodePwd()[j]);
			}
			for (int j = 0; decodePasswd[i].getUnionDecodePwd() != null && j < decodePasswd[i].getUnionDecodePwd().length; j++) {
				System.out.println("    " + decodePasswd[i].getUnionDecodePwd()[j]);
			}
		}
	}
	
	/**
	 * 解密数字字符串
	 * @param str
	 * @return
	 */
	public static DecodePasswd[] decodeNumberString(String str){
		String[] strs = str.split("");
		DecodePasswd[] decodePasswd = new DecodePasswd[str.length()];
		decodePasswd[0] = new DecodePasswd(new String[] {CHARACTERS[Integer.parseInt(strs[0])]}, null);

		DecodePasswd decodePwd = new DecodePasswd();
		setDecodePasswd(decodePwd,decodePasswd[0],strs[1]);
		if (Integer.parseInt(strs[0] + strs[1]) <= 26) {
			setDecodePasswd(decodePwd,null,strs[1],strs[0]);
		}
		decodePasswd[1] = decodePwd;
		for (int i = 2; i < strs.length; i++) {
			decodePwd = new DecodePasswd();
			setDecodePasswd(decodePwd, decodePasswd[i - 1], strs[i]);
			if (Integer.parseInt(strs[i - 1] + strs[i]) <= 26) {
				setDecodePasswd(decodePwd, decodePasswd[i - 2], strs[i], strs[i - 1]);
			}
			decodePasswd[i] = decodePwd;
		}
		return decodePasswd;
	}
	
	/**
	 * 计算第i个数字单独解密的密码。
	 * @param current 到第i个数字的密码对象
	 * @param _1_decodePasswd 到第i-1个数字的密码对象
	 * @param str 第i个数字
	 */
	public static void setDecodePasswd(DecodePasswd current, DecodePasswd _1_decodePasswd, String str) {
		int l = 0;
		if(_1_decodePasswd.getAloneDecodePwd() != null){
			l += _1_decodePasswd.getAloneDecodePwd().length;
		}
		if(_1_decodePasswd.getUnionDecodePwd() != null){
			l+= _1_decodePasswd.getUnionDecodePwd().length;
		}
		current.setAloneDecodePwd(new String[l]);
		
		String[] alonePwd = _1_decodePasswd.getAloneDecodePwd();
		String[] unionPwd = _1_decodePasswd.getUnionDecodePwd();
		int k = 0;
		if (alonePwd != null) {
			for (int i = 0; i < alonePwd.length; i++) {
				current.getAloneDecodePwd()[k] = alonePwd[i] + CHARACTERS[Integer.parseInt(str)];
				k++;
			}
		}

		if (unionPwd != null) {
			for (int i = 0; i < unionPwd.length; i++) {
				current.getAloneDecodePwd()[k] = unionPwd[i] + CHARACTERS[Integer.parseInt(str)];
				k++;
			}
		}
	}
	
	/**
	 * 计算第i-1个数字和第i个数字组合解密算得的密码
	 * @param current 到第i个数字的密码对象
	 * @param _2_decodePasswd 到第i-2个数字的密码对象
	 * @param str 第i个数字
	 * @param _1_str 第i-1个数字
	 */
	public static void setDecodePasswd(DecodePasswd current, DecodePasswd _2_decodePasswd, String str, String _1_str) {
		if (_2_decodePasswd == null) {
			current.setUnionDecodePwd(new String[1]);
			current.getUnionDecodePwd()[0] = CHARACTERS[Integer.parseInt(_1_str + str)];
			return;
		} else {
			int l = 0;
			if (_2_decodePasswd.getAloneDecodePwd() != null) {
				l += _2_decodePasswd.getAloneDecodePwd().length;
			}
			if (_2_decodePasswd.getUnionDecodePwd() != null) {
				l += _2_decodePasswd.getUnionDecodePwd().length;
			}
			current.setUnionDecodePwd(new String[l]);
		}
		String[] alonePwd = _2_decodePasswd.getAloneDecodePwd();
		String[] unionPwd = _2_decodePasswd.getUnionDecodePwd();
		int k = 0;
		if (alonePwd != null) {
			for (int i = 0; i < alonePwd.length; i++) {
				current.getUnionDecodePwd()[k] = alonePwd[i] + CHARACTERS[Integer.parseInt(_1_str + str)];
				k++;
			}
		}

		if (unionPwd != null) {
			for (int i = 0; i < unionPwd.length; i++) {
				current.getUnionDecodePwd()[k] = unionPwd[i] + CHARACTERS[Integer.parseInt(_1_str + str)];
				k++;
			}
		}
	}
}

class DecodePasswd {

	// 第i个数字单独解码的密码数组
	private String[] aloneDecodePwd;
	// 第i-1个数字和第i个数字联合解码的密码数组
	private String[] unionDecodePwd;

	public DecodePasswd() {}

	public DecodePasswd(String[] aloneDecodePwd, String[] unionDecodePwd) {
		this.aloneDecodePwd = aloneDecodePwd;
		this.unionDecodePwd = unionDecodePwd;
	}

	public String[] getAloneDecodePwd() {
		return aloneDecodePwd;
	}

	public void setAloneDecodePwd(String[] aloneDecodePwd) {
		this.aloneDecodePwd = aloneDecodePwd;
	}

	public String[] getUnionDecodePwd() {
		return unionDecodePwd;
	}

	public void setUnionDecodePwd(String[] unionDecodePwd) {
		this.unionDecodePwd = unionDecodePwd;
	}

}

算的结果为

数字字符串[1]有[1]种解码方法,解得的密码为:
    A
数字字符串[12]有[2]种解码方法,解得的密码为:
    AB
    L
数字字符串[123]有[3]种解码方法,解得的密码为:
    ABC
    LC
    AW
数字字符串[1231]有[3]种解码方法,解得的密码为:
    ABCA
    LCA
    AWA
数字字符串[12312]有[6]种解码方法,解得的密码为:
    ABCAB
    LCAB
    AWAB
    ABCL
    LCL
    AWL
数字字符串[123121]有[9]种解码方法,解得的密码为:
    ABCABA
    LCABA
    AWABA
    ABCLA
    LCLA
    AWLA
    ABCAU
    LCAU
    AWAU


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值