帖子地址: http://topic.csdn.net/u/20110523/12/12a128ad-8a0a-4eb9-b4a1-9cda06f23e39.html
看到帖子, 自己写了代码, 经测试结果一致
uuCount1 = GetCountByVal(911111111099999009);
1648888888779991781
速度提高很多, 自己非计算机专业, 复杂度是啥不懂, 知道了说下
原理看图片及代码, 代码很简单
ULONGLONG GetOneCount (ULONGLONG uuValue )
{
int uuCount ;
int nR ;
uuCount = 0;
for (; uuValue >0; )
{
nR = uuValue % 10;
uuValue = uuValue / 10;
if (nR == 1)
uuCount ++;
}
return uuCount ;
}
ULONGLONG GetFullCount (ULONGLONG uuMaxValue )
{
ULONGLONG uuTotalCount ;
ULONGLONG i ;
uuTotalCount = 0;
for (i =0; i <=uuMaxValue ; i ++)
{
uuTotalCount += GetOneCount (i );
}
return uuTotalCount ;
}
// dwVal < 100
int GetBaseCountByVal (DWORD dwVal )
{
if (dwVal >= 100)
{
assert (0);
return 0;
}
if (dwVal == 0)
return 0;
if (dwVal < 10)
return 1;
if (dwVal < 20)
{
if (dwVal > 10)
return dwVal -10+3; // 3= (1) + (10) + (11)
else
return dwVal -10+2; // 2= (1) + (10)
}
if ( (dwVal % 10) >= 1)
return dwVal /10 + 10 + 1;
else
return dwVal /10 + 10;
}
#define BASE100 20
/*
f(578) = 5*f(100)+ s_bBaseCount[5]*78 + f(78)
f(578) = 5*f(100)+f(5)*100+ s_bBaseCount[5]*78 + f(78)
*/
// dwVal > 100
ULONGLONG GetCountByVal (ULONGLONG uuVal )
{
ULONGLONG uuQ , uuR ;
ULONGLONG uuCount ;
ULONGLONG uuOneCount ;
if (uuVal < 100)
return GetBaseCountByVal (uuVal );
uuQ = uuVal / 100;
uuR = uuVal % 100;
uuCount = uuQ * BASE100 ;
uuCount += GetCountByVal (uuQ -1) * 100;
uuOneCount = GetOneCount (uuQ );
uuCount += uuOneCount *(uuR +1);
uuCount += GetCountByVal (uuR );
return uuCount ;
}
// 测试代码
void CDlg3 ::OnBnClickedButton1 ()
{
ULONGLONG uuVal , i ;
ULONGLONG uuOneCount ;
ULONGLONG uuCount1 ;
ULONGLONG uuCount2 ;
ULONGLONG uuCount3 ;
uuCount1 = GetCountByVal (911111111099999009);
for (i =10; i <1000000; i ++)
{
uuOneCount = GetOneCount (i );
uuCount1 = GetFullCount (i );
if (i < 100)
uuCount2 = GetBaseCountByVal (i );
uuCount3 = GetCountByVal (i );
if (i %100 == 0)
ATLTRACE ("%5I64d: %5I64d %5I64d %5I64d %5I64d/n" , i , uuOneCount , uuCount1 , uuCount2 , uuCount3 );
if (uuCount1 != uuCount3 )
assert (0);
i += rand () % 30;
}
}