欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

解码方法

程序员文章站 2022-07-05 14:01:03
...

有一个消息包含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