“从1到n整数中1出现的次数”的非递归解法

来源:互联网 发布:奶酪发苦 知乎 编辑:程序博客网 时间:2024/05/22 17:03


//by L&L//《剑指offer》面试题32,P174//问题:从1到n整数中1出现的次数////非递归方法描述://先取一个具体的例子,假设n = 9999;//令个位为1,则有(999+1)*1个数;//令十位为1,则有(99 +1)*10个数;//令百位为1,则有(9  +1)*100个数;//令千位为1,则有(0  +1)*1000个数;//以上相加,得...共4000//上面这个例子太特殊,再看一个更具普遍性的例子://假设n = 2014://令个位为1,则有(201+1)*1个数;//令十位为1,则有(20   )*10+1*(4+1)个数;//令百位为1,则有(2    )*100个数;//令千位为1,则有(0  +1)*1000个数;//以上相加,得202+205+200+1000=1607///////可以看出,有三种情况需要考虑:该位上数字小于1,等于1,大于1#include <iostream>#include <time.h>int NumberOf1Between1AndN(unsigned n);//原始方法,效率不行int NumberOf1(unsigned n);int NumberOf1Between1AndN2(unsigned n);//高效方法,非递归bool GetNumber(const unsigned& n, unsigned ui,    unsigned* pHi, unsigned* pBe, unsigned* pLo, unsigned* pBase);int main(){clock_t  clockBegin, clockEnd;unsigned ui = 88801666u;std::cout << "计算从1到" << ui << "整数中1出现的次数" <<std::endl;std::cout << "begin:" << std::endl;clockBegin = clock(); std::cout << NumberOf1Between1AndN(ui);clockEnd = clock();std::cout << ", used " << clockEnd - clockBegin << "ms" << std::endl;std::cout << NumberOf1Between1AndN2(ui);std::cout << ", used " << clock() - clockEnd << "ms" << std::endl;system("pause");return 0;}//原始方法,效率不行int NumberOf1Between1AndN(unsigned n){int number = 0;for (unsigned i = 1; i <= n; ++i){number += NumberOf1(i);}return number;}int NumberOf1(unsigned n){int number = 0;while (n){if (1 == n % 10){++number;}n /= 10;}return number;}//高效方法,非递归int NumberOf1Between1AndN2(unsigned n){int number = 0;unsigned hi = 0, be = 0, lo = 0;unsigned uiBase = 1;for (unsigned i = 1, ii = 1; ii < n * 10; ++i, ii *= 10){if (GetNumber(n, i, &hi, &be, &lo, &uiBase)){if (be > 1)number += (hi + 1) * uiBase;else if (be < 1)number += hi * uiBase;elsenumber += hi * uiBase + (lo + 1);}}return number;}bool GetNumber(const unsigned& n, unsigned ui,    unsigned* pHi, unsigned* pBe, unsigned* pLo, unsigned* pBase){if (0 == ui)return false;unsigned uiBase = 1;while (--ui)uiBase *= 10;*pHi = n / (uiBase * 10);*pBe = n % (uiBase * 10);*pLo = *pBe % uiBase;*pBe = *pBe / uiBase;*pBase = uiBase;return true;}/*输出:计算从1到88886666整数中1出现的次数begin:72345037, used 9024ms72345037, used 1ms请按任意键继续. . .*/


0 0
原创粉丝点击