- 原理
动态规划,设dp[i]为[0,i]之间的数字与字母的合法匹配的总数。先计算第i个数字单独匹配一个字母的情况下的数量(设为 xi ),再计算第i-1和i个数字组成一个两位数匹配一个字母的情况下的数量(设为 yi ),则 dp[i]=xi∗dp[i−1]+yi∗dp[i−2] 。 合法匹配的数量列表
1)1位数数字 匹配数目 1-9 1 * 9 2) 2位数
十位数 个位数 匹配数目 1 0-9 1 2 0-6 1 * 0-6 2 * 7-9 1 1 * 9 2 * 6 * * 15 算法源码
#define MOD_NUMBER 1000000007
#define SYMBOL_CASE(symbol) case symbol:
#define ZERO_CASE \
SYMBOL_CASE('0')
#define ONE_CASE \
SYMBOL_CASE('1')
#define TWO_CASE \
SYMBOL_CASE('2')
#define ONE_SIX_CASE \
ONE_CASE \
TWO_CASE \
SYMBOL_CASE('3') \
SYMBOL_CASE('4') \
SYMBOL_CASE('5') \
SYMBOL_CASE('6')
#define SEVEN_NINE_CASE \
SYMBOL_CASE('7') \
SYMBOL_CASE('8') \
SYMBOL_CASE('9')
#define ONE_NINE_CASE \
ONE_SIX_CASE \
SEVEN_NINE_CASE
#define ZERO_SIX_CASE \
ZERO_CASE \
ONE_SIX_CASE
#define ZERO_NINE_CASE \
ZERO_CASE \
ONE_NINE_CASE
#define ASTERISK_CASE \
SYMBOL_CASE('*')
#define PROCESS_CASE(condition, result) \
condition \
number = result; \
break;
int num_ways_one_char(char c)
{
int number = 0;
switch (c)
{
PROCESS_CASE(ONE_NINE_CASE, 1)
PROCESS_CASE(ASTERISK_CASE, 9)
default:
break;
}
return number;
}
int num_ways_two_char(char c1, char c2)
{
int number = 0;
switch (c1)
{
ONE_CASE
switch (c2)
{
PROCESS_CASE(ZERO_NINE_CASE, 1)
PROCESS_CASE(ASTERISK_CASE, 9)
default:
break;
}
break;
TWO_CASE
switch (c2)
{
PROCESS_CASE(ZERO_SIX_CASE, 1)
PROCESS_CASE(ASTERISK_CASE, 6)
default:
break;
}
break;
ASTERISK_CASE
switch (c2)
{
PROCESS_CASE(ZERO_SIX_CASE, 2)
PROCESS_CASE(SEVEN_NINE_CASE, 1)
PROCESS_CASE(ASTERISK_CASE, 15)
default:
break;
}
break;
default:
break;
}
return number;
}
int numDecodings(char* s)
{
int curr_c;
int pre_c;
long long curr_res;
long long pre_res = 1;
long long next_res;
curr_c = *(s++);
curr_res = num_ways_one_char(curr_c);
pre_c = curr_c;
curr_c = *(s++);
if(!curr_c || !curr_res)return curr_res;
do
{
next_res = ((curr_res * num_ways_one_char(curr_c) % MOD_NUMBER) +
(pre_res * num_ways_two_char(pre_c, curr_c) % MOD_NUMBER)) % MOD_NUMBER;
pre_res = curr_res;
curr_res = next_res;
if (!curr_res) return 0;
pre_c = curr_c;
curr_c = *(s++);
} while (curr_c);
return curr_res;
}