1. 程式人生 > >[日常練習] 1. 基於素數及閏年判斷、列印乘法口訣表的C語言實現

[日常練習] 1. 基於素數及閏年判斷、列印乘法口訣表的C語言實現


在日常學習中,我們能很快的分析得到一個數是否是素數,瞭解它的判定法則,但是要是給你100個數,你需要花費多少時間才能判斷其中的素數呢?又能保證多少正確率呢?好吧,即便你是數學巧算能手、珠心算大神,100的總量對於你來講是九牛一毛!!!但是我給你10000+個(我就是刻意為難你胖虎~),您慢慢算吧!

乘法口訣表算是我們學習數學的一個“大障礙”,小時候背不出來、背錯被揍的經歷大多數人都經歷過,但是能用自己所學的程式設計知識列印得到一份完整的9*9的乘法表嗎?那要是n*n呢?

閏年判斷也是一個程式設計學習的初步難點,重在它的邏輯上面,有很大一部分同學都會漏掉某些“特殊的年”,像是1600,2000等,為什麼會出現這個情況呢?我們能否在大量年份資料面前可以很快、準的判斷出裡面那些是閏年,那些不是閏年,並且統計它的個數呢?


練習題目:

1. 列印100~200 之間的素數
2. 輸出乘法口訣表
3. 判斷1000年---2000年之間的閏年

題目分析及程式碼:

1. 在C語言中素數的判別法很多,最基本的是一個數i,如果它能夠整除前面的i-1個數,那麼它不是素數,反之則是。也有將判斷條件從i-1縮減到\sqrt i,來減小判斷迴圈的次數。在此我們選擇後者進行判斷。當然,也有很多判斷方式方法,在以後的學習中一定要學習各個方法的長處,注意總結!

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

int main()
{
	int i = 0;
	int count = 0;

	for(i = 101; i<200; i+=2)            //偶數在此不需要進行判斷
	{
		int j = 0;
		for(j=2; j<=sqrt(i); j++)    //演算法優化
		{
			if(i%j == 0)
			{
				break;
			}
		}

		if(j>sqrt(i))
		{
			count++;             //計算素數個數
			printf("%d ", i);    //依次列印各個素數
		}
	}

	printf("\ncount = %d\n", count);     //列印素數總數
	return 0;
}

上面就有我們的C語言程式程式碼及執行結果,是不是正確呢?那當然是正確的了...

在此我們需要注意到的是:

1. 偶數不需要進行素數判斷,故i可以累次遞加2,這樣就會減少很大一部分無用的迴圈。但是,i的初值也要相應的修改!

2. 也是在判斷的條件上,選用\sqrt i進行處理,相較於最基本的以i-1進行判斷的方法,也是很大進步。

3. 計算所求得的素數的個數,count可以直接求出,但是也是要注意它在迴圈體中的位置。

回味:

素數可謂是很重要、特殊的數字了,在數學上有很大的作用,有著名的“哥德巴赫猜想”,素數在此扮演了重要的角色。在C語言中的素數判斷程式中,首先需要很熟練的將其寫出來。之後需要再學習2--4種其它優秀的判別方法,優化的演算法思想是素數判別問題的重點。這就需要自己去挖掘了!!!


2. 列印乘法口訣表,資料依次遞加,格式規整,這無疑是要使用到迴圈的。然而迴圈的使用我們需要注意到的是:迴圈變數的賦初值、限值條件這兩個重要因素。在9*9表中,它的第一特徵是個正下三角形,要是從列的角度進行觀看的話,我們會發現,列數並不能很顯著的展示它的特徵。來反觀行數,第一行1個,第二行2個,第三行3個...第i行i個,那麼一行的算術個數就與被乘數相同,那麼這樣的一個累加過程就可以用迴圈實現!

#include<stdio.h>
int main()
{		
	int i = 0;
	int j = 0;
	for(i=0; i<=9; i++)          //尋找乘數與被乘數的關係
	{
		for(j=1; j<=i; j++)      //9*9乘法表,每一行的個數等於i,而j每次都要從1開始,所以在此j的限制條件可以得到j<=i
		{
			printf("%d*%d=%2d ", i, j, i*j);   //列印每一行,注意 %2d 的使用讓列印格式更加整齊
		}
		printf("\n");            //列印完畢一行時,要進行換行
	}
	return 0;
}

上面就是我們的C語言實現原始碼和結果,這顯然是正確的!

在此我們需要注意到的是:

1. 需要將問題轉化為迴圈的問題,需要進行一定的轉化,j的初值以及定解問題,這就需要程式的思維!

2. 在初次列印的時候,我們會發現每個數字並不能對齊,這就是二位數字所佔的位數的問題,需要進行調整。''%d*%d=%2d'',這是一個很良好的調整方案,但是要是產生三位數了呢?要是需要進行“智慧的對齊”呢?

回味:

9*9乘法表代表著“童年的記憶”,在C語言實現中,是迴圈很好的體現。在此我們編了9*9的,可以順利解決,也能解決它的排版問題。但是再讓我們回到最初的問題,我們是否可以從列中尋找到其中的關係?能否進行“智慧的對齊”呢?列印9*9乘法表是最基礎的程式了,一定要牢記!


3.閏年4年一次,一次一年多一天。要是誰的生日正正好好的就在那多的一天上面,也就是罕見的2月29日,4年一次的生日也是可以好好的操辦一下了。判斷閏年的條件我們可以得到被4整除,被400整除,迴圈結構這要怎麼實現呢?在判斷條件如此多的情況下,會不會缺漏條件呢?拭目以待!

 

#include<stdio.h>
int main()
{
	int year = 0;
	int count = 0;
	for(year=1000; year<=2000; year++)     
	{
		if(((year%4==0)&&(year%100!=0))||(year%400==0))    //判斷條件
		{
			printf("%d ",year);                            
			count++;                                       //計數1
		}
	}
	if(year%400 == 0)                                      //被400整除也是閏年
	{
		count++;                                           //
		printf("%d ",year);
		
	}
	printf("\n1000--2000年閏年總數:%d 年\n",count);
	return 0;
}

上面就是我們的C語言實現原始碼和結果,這我也無法保證正確性了...大家可以自行驗證一波!

在此我們需要注意到的是:

1. 我們在判斷條件的時候,用到了“邏輯與”、“邏輯或”,這裡判斷的時候,電腦會偷懶懶的!!!在“邏輯或”前件為真時,整體就已經為真了,後件就不需要進行判斷了,電腦也很聰明,自動跳過這個判斷。這當然不是我們所需要的!!! 在if語句中,大家可以將“邏輯或”中的順序進行交換,看看結果是否有變化。

2. 發現程式在中刪減某些項的程式碼(刪掉if判斷語句)不影響最後的結果,這個閏年的判斷的程式是過於繁瑣還是我的操作有問題呢?

3. 閏年的判斷,順序還有什麼要注意的呢???

回味:

在閏年判斷裡面其實邏輯並不複雜,但是總是會出現某些年份丟掉了,此時,我們要看看那些邏輯被丟掉了呢?還是有些問題被我們忽略掉了?這就要考我們問題的細心程度、問題的掌握程度了,得好好積累了!

 

日常:

以後會進行一些習題的處理,學習中的特立獨行的想法也會再次提出。此外對於Matlab以及LaTeX的學學習可能也會 放到上面,寫寫自己的心得,希望能夠在自己的學習之路上。它能記錄下我的點滴進步!