C語言學習1:素數的判定與素數表的生成
摘要:本文主要探究素數的判別和素數表的生成,爲初學時寫下作爲學習筆記。
一、素數的判定
1.平方根以下遍歷法
基本思想:
由數學證明可知,若要判定一個數是否爲素數,只需將其除以 [ 2 , sqrt(x) ) , 其中x是這個數本身。另外爲了優化計算,可以先判定是否爲非2整數。基於這個思想,我們可以給出以下代碼。
int isPrime ( int x )
{
int ret = 1;
int i;
if ( x==1 || x%2 == 0 && x!=2 )
{
ret = 0;
}
for ( i=3; i<sqrt(x); i+=2 )
{
if ( x % i == 0 )
{
ret = 0;
break;
}
}
return ret;
}
2.素數表法
基本思想:
判定一個數是不是素數,只需判定它是不是之前的所有素數的倍數即可,因此,我們可以使用遞歸的方法,邊擴充素數表邊判定是否爲素數,此方法適合大批量的判定,也適用於素數表的生成。
在這裏插入#include <stdio.h>
int isPrime(int x, int KnownPrimes[], int numberofKnownPrimes );
int main()
{
const int number = 100;
int prime[100] = {2};
int count = 1;
int i = 3;
while ( count < number )
{
if ( isPrime( i, prime, count ) )
{
prime[count++] = i;
}
i++;
}
for ( i=0; i<number; i++ )
{
printf("%d",prime[i]);
if ( (i+1)%5 )
{
printf("\t");
}
else printf("\n");
}
return 0;
}
int isPrime(int x, int KnownPrimes[], int numberofKnownPrimes )
{
int ret = 1;
int i;
for ( i=0; i<numberofKnownPrimes; i++ )
{
if ( x % KnownPrimes[i] == 0 )
{
ret = 0;
break;
}
}
return ret;
}
二、素數表的生成
在上面一.2中我們給出了一種素數表的生成方法,它是基於之前的素數表進行遞歸的方法,接下來我們將給出另一種方法。
基本思想:
從2開始,將目前操作數的倍數標記爲非素數,再將操作數換成下一個“目前爲素數的數”,如此直至到達範圍終點,留下的數即爲素數。
#include <stdio.h>
int main()
{
const int maxNumber = 25;
int isPrime[maxNumber];
int i;
int x;
for ( i=0; i<maxNumber;i++ )
{
isPrime[i] = 1;
}
for ( x=2; x<maxNumber; x++ )
{
if ( isPrime[x] )
{
for ( i=2; i*x<maxNumber; i++ )
{
isPrime[i*x] = 0;
}
}
}
for ( i=2; i<maxNumber; i++ )
{
if ( isPrime[i] )
{
printf("%d\t",i);
}
}
printf("\n");
return 0;
}
三、總結感悟
- 由1.1我們可以看到,數學中的知識對於簡化計算機的算法具有很大作用,我們不能單純的將計算機作爲執行大量簡單指令的工具,更重要的是實現程序員自身邏輯性和數學優化能力,減輕計算機的負擔。
- 由1.2我們可以看到,遞歸(姑且允許我這麼表達)的思想可以用在某些算法中,起到優化的作用,但是由於我們初學者將循環使用的較爲死板,往往意識不到這些問題,這就要求我們放開眼界、解放思想並多加練習。
- 最想說的是2.1,這個算法將人類邏輯中的優化和計算機擅長的遍歷結合起來,有效的規避了人類思想中不適合大量數的遍歷和計算機算法過於“膚淺”帶來的計算量過大問題,這算是我學習C語言遇到的第一個自認爲較爲不錯的程序吧,與君共勉,Cheers!
附:學習來源:中國大學Mooc-浙大翁愷老師-C語言程序設計-8.2:數組運算
鏈接 :https://www.icourse163.org/learn/ZJU-9001#/learn/content?type=detail&id=129003&cid=145002&replay=true