@nhahtdh 的答案是完全正确的。但是,如果需要大量数字,计算组合因子可能会有点棘手(请参阅注释以了解这样做的好方法)。
这是一种不通过阶乘但使用递归来计算相同数字的方法:不考虑函数 int cntPass(int N,int L,int U,int D),而是添加最后一个参数,它表示可以是 3 中任何一个的位数:
int cntPass(int N,int L,int U,int D,int A)
注意我们有 A = NLUD。现在,递归基于对第一个字符的选择:我们有 26 个小写字母选择,26 个大写字母选择,10 个数字选择。
现在,给定 N、L、U、D 和 A,可以
- 将小写字母作为第一个字符-> 26 种可能性。对于这些可能性中的每一种,我们对其余密码都有 cntPass(N-1,L-1,U,D,A) 可能性。注意如果L=0,这不起作用,除非A>0,即仍有一些字符可以自由选择。在这种情况下,我们也有 26 种可能性,每个可能性都有 cntPass(N-1,L,U,D,A-1)。
- 大写的同上
- 同上的数字。
为了结束递归,我们可以设置 N=1 时的可能性数量,或者等效地设置 N=0 时的数量(为符号 1)。
这是一个 Matlab 代码(使用 Matlab 进行快速测试),它使得它:
function [number]=Nword(N,LowerCase,UpperCase,Digit,Any)
number = 0;
if ( LowerCase > 0)
number = number + 26*Nword( N-1, LowerCase-1, UpperCase, Digit, Any);
elseif (Any > 0)
number = number + 26*Nword( N-1, LowerCase, UpperCase, Digit, Any-1);
end
if ( UpperCase > 0)
number = number + 26*Nword( N-1, LowerCase, UpperCase-1, Digit, Any);
elseif( Any > 0)
number = number + 26*Nword( N-1, LowerCase, UpperCase, Digit, Any-1);
end
if ( Digit > 0)
number = number + 10*Nword( N-1, LowerCase, UpperCase, Digit-1, Any);
elseif( Any > 0)
number = number + 10*Nword( N-1, LowerCase, UpperCase, Digit, Any-1);
end
if (number == 0)
number = 1;
end
return