從1到n的數中1出現的個數&&尋找醜數

從1到n的數中1出現的個數,最簡單的思路就是從1到n求每個數字中1的個數,這樣就是速度太慢了。

可以尋找規律,假設數爲abcde,c在百位上,求百位上的數字的方法:如果c等於0或者大於1,1的個數只與左邊有關(即ab),如果c等於1,1的個數和左邊右邊都有關(即de)。

具體見代碼:

#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;

int basecalsum(int number){
	int sum =0;
	for(int i =1;i<=number;i++){
		int temp = i;
		while(temp != 0){
			if(temp%10 == 1)
				++sum;
			temp/= 10;
		}
	}
	return sum;
}

int fastcalsum(int number){
	int leftnum,rightnum,curnum,sum =0;
	int pos =1;
	while(number/pos!= 0){
		leftnum = number/(pos*10);
		rightnum= number-(number/pos)*pos;
		curnum = (number/pos)%10;
		switch(curnum){
		case 0:
			sum += leftnum*pos;
			break;
		case 1:
			sum += leftnum*pos+rightnum+1;
			break;
		default:
			sum += (leftnum+1)*pos;
			break;
		}
		pos *=10;
	}
	return sum;
}

int main(){
	clock_t start,end;
	double duration;
	int sum1,sum2;
	start = clock();
	sum1 = basecalsum(100000000);
	end   = clock();
	printf("基本方法輸出爲%d,損耗時間爲%f秒\n",sum1,(double)(end-start)/CLOCKS_PER_SEC);
	start = clock();
	sum1 = fastcalsum(100000000);
	end   = clock();
	printf("快速的方法輸出爲%d,損耗時間爲%f秒\n",sum1,(double)(end-start)/CLOCKS_PER_SEC);
	system("PAUSE");
	return 0;
}

醜數指的是因子中只有2,3,5的數,比如求第1500個醜數也可以一個一個的算,直到1500.如果數字很大還是太慢。

所以我們考慮用空間換時間,即1爲最小的醜數,那麼其它醜數都可以分解成更小的醜數乘積。所以用數組存儲之前的醜數,然後進行計算。爲了簡化計算可以不用數組中的每個數都來判斷,可以每算出一個進行對比,如果是小於則跳過。說的不太清楚,具體看代碼。

#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;
//基本方法
bool isurgly(int a){
	while(a%2 == 0)
		a/=2;
	while(a%3 == 0)
		a/=3;
	while(a%5 == 0)
		a/=5;
	return (a==1) ? true : false;
}
int basefindurgly(int number){
	int count = 0;
	int num = 0;
	while(count<number){
		++num;
		if(isurgly(num))
			++count;
	}
	return num;
}
//快速方法
int fastfindurgly(int number){
	//int *urgnum = (int *)malloc(sizeof(number+1));
	int *urgnum = new int[number];
	int pos2,pos3,pos5;
	pos2 = pos3 = pos5 =0;
	urgnum[0] = 1;
	int i =1;
	while(i < number){
		int temp = urgnum[pos2]*2;
		if(temp >urgnum[pos3]*3)
			temp = urgnum[pos3]*3;
		if(temp >urgnum[pos5]*5)
			temp = urgnum[pos5]*5;
		urgnum[i] = temp;
		if(urgnum[pos2]*2 <= urgnum[i])
			++pos2;
		if(urgnum[pos3]*3 <= urgnum[i])
			++pos3;
		if(urgnum[pos5]*5 <= urgnum[i])
			++pos5;
		++i;
	}
	int result = urgnum[number-1];
	delete [] urgnum;
	return result;
}

int main(){
	int result;
	clock_t start,end;
	start = clock();
	result = basefindurgly(1500);
	end = clock();
	printf("結果爲%d,時間爲%f seconds\n",result,(double)(end-start)/CLOCKS_PER_SEC);
	start = clock();
	result = fastfindurgly(1500);
	end = clock();
	printf("結果爲%d,時間爲%f seconds\n",result,(double)(end-start)/CLOCKS_PER_SEC);
	system("PAUSE");
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章