Question: Please 1 ~ The number of 1 in the integer n.
The general practice is to first write a sub-function with the right shift of 1, calculate the number of 1 in each number, and then traverse 1 ~ N. sum is the answer.
In Baidu Library (http://wenku.baidu.com/view/6722a969af1ffc4ffe47ac18.html) to see such a solution:
// Calculate the integer 1 ~ Total number of 1 in N ulonglong sum1s (ulonglong N) {ulonglong icount = 0; ulonglong ifactor = 1; ulonglong ilowernum = 0; ulonglong icurrnum = 0; ulonglong ihighernum = 0; while (N/ifactor! = 0) {ilowernum = N-(N/ifactor) * ifactor; icurrnum = (N/ifactor) % 10; ihighernum = N/(ifactor * 10); Switch (icurrnum) {Case 0: icount + = ihighernum * ifactor; break; Case 1: icount + = ihighernum * ifactor + ilowernum + 1; break; default: icount + = (ihighernum + 1) * ifactor; break;} ifactor * = 10;} return icount ;}
It says, "This method only needs to analyze N to get F (N), avoiding traversing from 1 to n, the time complexity of the number N whose input length is Len is O (LEN), that is, O (Ln (N)/ln (10) + 1 ). On the author's computer, the calculation of N = 100 000 000, compared to the 40 seconds of the first method, this algorithm can return results in less than 1 millisecond, the speed is increased by at least times."
However, I don't know why I failed to run correctly. Although I didn't understand my ideas, I thought it was quite enlightening. I started with N and analyzed it directly to avoid traversing 1 ~ N, So I studied it for a while and observed that in binary representation, the N-bit 000... 000 ~ The numbers of 0 and 1 between 111 and 111 are equal! As shown in:
So the implementation method based on the recursive method is as follows, And the recursive depth does not exceed n's maximum non-0-bit digits. Is it faster?
// Calculate the integer 1 ~ Total number of 1 in N ulonglong sum1s (ulonglong N) {If (n <= 2) {return N;} ulonglong ifactor = 3; ulonglong ilen = 1; while (n> = ifactor) // find the number of largest, less than N, all bits are 1 {ifactor <= 1; ifactor | = 1; + + ilen;} ifactor >>=1; ulonglong icount = (ifactor + 1) * ilen)> 1; // The number of zeros in this region is equal to If (ifactor = N) {return icount ;} else {return (icount + N-ifactor + sum1s (N & (ifactor )));}}