您的位置:首页 > 其它

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

2016-05-24 10:55 274 查看
/*
输入一个整数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);
else
numFirstDigit = 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);

retu
4000
rn 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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: