讨论google面试题 - 在从1到n的正数中1出现的次数

 

帖子地址: 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;

    }

 

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值