練習:求完數問題


題目:

一個數如果恰好等於它的因子之和,這個數就稱為"完數"。例如,6的因子為1、2、3,而6=1+2+3,因此6是“完數”。編程序找出1000之內的所有完數,並按下面格式輸出其因子:

  6     Its    factors     are   1     2     3

原帖:代碼評析與重構——求完數問題

下面是我的代碼,思想不多說,貪心算法。

 

//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define DIVISERS_MAX_LENGTH  (1024)
#define TOP (10000)

int main(void)
{
	/*
	 * 儲存因子,成對的儲存。例如6
	 * 1,6, 2,3 
	 */
	int divisers[DIVISERS_MAX_LENGTH] = {0};
	int divisers_count = 0;

	/* 要判斷的數 */
	int number;
	int sum;

	/* 指定 i的最大值, */
	int i_max;
	int i ;
	int diviser;

	for(number = 2; number < (TOP + 1) ; ++number ){
		/* 所有數可以被 1 和 自己整除,所以,下面for 從 2 開始 
		   sum = 1;
		 count = 2;
		 i = 2;
		 i_max = number /2
		 */
		divisers[0] = 1;
		divisers[1] = number;

		/* 關於 i < i_max .
		 因為整除啊,
		 m = i / n
		 如果 i 能被 n 整除,則,n 最小,m最大。
		 隨着循環進行 最小和最大不斷被求出來,所以超過最大的就不用再算了。
		 
		 其實,這個地方使用 i < sqrt(number) +1 最好了。
		 */
		for (divisers_count = 2,i = 2,sum = 1,i_max = sqrt(number)+1; i < i_max; ++i){
			if (!(number % i)){
				if (!(divisers_count < DIVISERS_MAX_LENGTH)){
					fprintf(stderr, "Too many divisers\n number:%d count:%d\n",number,divisers_count);
					break;
				}
				divisers[divisers_count] = i;
				diviser = number/i;

				sum += i;
				++ divisers_count;				
				if (diviser != i) {
					divisers[divisers_count] = diviser;
					sum += diviser;
					++ divisers_count;
				}
				
				if (sum > number) break;
			}
		}

		/* 下面是輸出 */
		if (sum == number){
			printf("%d ,Its factors are : ", number);
			for (i =0; i < divisers_count ; i += 2 ){
				printf ("%d ",divisers[i]);
			}
			/*
			 這個因為是倒敘輸出,數組可能不是偶數,所以要判斷開始的位置
			 i的開始的位置應該是:
			 i = (count -1 )- ( -((count-1) -(i-2)) +1 )
			 化簡后 
			 i = 2*count -i -1;
			 */
			for (i = 2*divisers_count -i -1; i > 2; i-=2 ){
				printf("%d ",divisers[i]);
			}
			printf("\n");
		}
	}
	/* 結束了。。。*/
	printf("end\n");
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM