我遇到了这个解决方案,检查一个数字是否为pandigital(一个n位数字,它使用所有数字1到n恰好一次,例如1234)。
private boolean isPandigital(int n){
int digits = 0;
int numDigits = String.valueOf(n).length();
for (; n > 0; n /= 10){
digits += (1 << (n - ((n / 10) * 10) - 1));
}
return digits == ((1 << numDigits) - 1);
}
for循环在每个循环中取一个数字(1234,123,12,1)。循环内部:
(n - ((n / 10) * 10) - 1)
评估n的最后一位数并取走1。
我理解这种方法在物理上是做什么的,但是pandigital数字的特性是什么呢?
答案 0 :(得分:3)
它所利用的属性是对于长度为n的pandigital输入,对数字求和必须等于(n +(n - 1)+(n - 2)... + 1)这相当于(n *(n + 1))/ 2.但是,不是用十进制算法,而是使用二进制位进行算法。
它使用每个十进制数字来递增二进制数字。对于十进制数字d,(d-1)处的二进制位递增。即,十进制数字3变为(1 <&lt;&lt;&lt;&lt;&lt;&lt;&quot;(&lt;&lt;&lt;&quot;(3 - 1)),这将增加第二个二进制数字将它们相加并与预期值进行比较。预期值是每个二进制数字将根据输入的长度设置。如果您的输入是1234,则每个二进制位将被设置为4位二进制值(二进制1111 =十进制15,来自((1 << numDigits) - 1)
)。
答案 1 :(得分:0)
未使用任何特定属性。
诀窍是,当你找到一个数字i时,你将(功率i为2)加到可变数字上,即在这个整数中设置一个比特。在该过程结束时,如果数字=(2到幂i)-1,则n个数字的数字将是pandigital,即数字的n个低位全部设置为1。
只是为了好玩,你可以以递归的方式做到这一点:
bool ispandigital = testpandigital(n.ToString()) ;
private bool testpandigital(string nbr)
{
string digit=str.Length.ToString() ;
return nbr=="0" || (nbr.Contains(digit) && testpandigital(nbr.Replace(digit,"")) ;
}