从1到n整数中1出现的次数

来源:互联网 发布:免费的读书软件 编辑:程序博客网 时间:2024/04/30 13:23

/*输入一个整数n,求从1到n这个n个整数的十进制表示中1出现的次数。例如,输入12,从1到12这些整数中包含1的数字有1,10,11,12。1一共出现了5次*/#include "iostream"#include "algorithm"using namespace std;int count1Num(int num){int count = 0;while (num != 0){if (num % 10 == 1)count++;num = num / 10;}return count;}//暴力求解int Count1Appearance0(int n){if (n <= 0)return 0;int count = 1;int i = 10;while (i <= n){count += count1Num(i);i++;}return count;}//第二种方法,找规律,一位一位看int numberOf1(const char* strN){if (!strN || *strN < '0' || *strN >'9' || *strN == '\0')return 0;int first = *strN - '0'; //最高位unsigned int length = static_cast<unsigned int>(strlen(strN));if (length == 1 && first == 0)return 0;if (length == 1 && first > 0)return 1;//假设strN是“21345”,numFirstDigit是数字10000-19999的第一个位中的数目int numFirstDigit = 0;if (first > 1)numFirstDigit = pow(10, length - 1);elsenumFirstDigit = atoi(strN + 1) + 1;//atoi(strN+1)除开最高位剩下的位数1345//numOtherDigits是1345~21345除了第一位之外的数位中的数目int numOtherDigits = first * (length-1) * pow(10, length - 2);//numRecursive是1-1345中1的数目int numRecursive = numberOf1(strN + 1);return numFirstDigit + numOtherDigits + numRecursive;}int Count1Appearance1(int n){if (n <= 0)return 0;char strN[50];sprintf_s(strN, "%d", n);return numberOf1(strN);}#include "ctime"void test(){clock_t t0 = clock();cout << Count1Appearance0(999999) << endl;cout << clock() - t0 << "ms" << endl;cout << endl;t0 = clock();cout << Count1Appearance1(999999) << endl;cout << clock() - t0 << "ms" << endl;}int main(){test();return 0;}
运行结果:

600000
87ms

600000
1ms


算法0的复杂度:O(n*lg(n))。算法1:lg(n)


0 0
原创粉丝点击