有一个消息包含A-Z通过以下规则编码:
'A' -> 1
'B' -> 2
...
'Z' -> 26
现在给你一个加密过后的消息,问有几种解码的方式,写一个函数实现。
格式:
输入行第一行输入一个加密后的消息即一个正整数,最后输出可以实现的解码方式的个数。
样例输入
12
样例输出
AB
L
解题思路如下:
数组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