1. 程式人生 > >C語言中素數的快速判斷和篩法建立。

C語言中素數的快速判斷和篩法建立。

素數是一類很有用的數,至今為止,沒有任何人發現素數的分佈規律,也沒有人能用一個公式計算出所有的素數。但素數的判斷和建立是有法可循的。

常用方法一:優化的列舉法(效率O(n*sqrt(n))),按照素數的定義從2-列舉到SQRT(N)。方法簡單易懂,這個用於判斷可以,但是建立的話時間過長。

int isprime(int n)
{
    for (int i=2;i<=sqrt(n);i++)
    {
        if (n%i==0)
            return 0;
    }
    return 1;
}

常用方法二:篩法。(效率O(n))

篩法的意思遵循一個原則,素數i的倍數一定不是素數。

(以下為轉載)

一個簡單的篩素數的過程:n=30。

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

第 1 步過後2 4 ... 28 30這15個單元被標成false,其餘為true。

第 2 步開始:

     i=3;  由於prime[3]=true, 把prime[6], [9], [12], [15], [18], [21], [24], [27], [30]標為false.

     i=4;  由於prime[4]=false,不在繼續篩法步驟。

     i=5;  

由於prime[5]=true, 把prime[10],[15],[20],[25],[30]標為false.

     i=6>sqrt(30)演算法結束。

第 3 步把prime[]值為true的下標輸出來:

     for(i=2; i<=30; i++)

     if(prime[i]) printf("%d ",i);

結果是 2 3 5 7 11 13 17 19 23 29

篩法還可以優化,於是有了方法三:優化篩法。

把所有偶數都去掉,時間複雜度進一步降低。

模板:

int prime(int a[],int n)
{
    int i,j,k,x,num,*b;
    n++;
    n/=2;
    b=(int *)malloc(sizeof(int)*(n+1)*2);
    a[0]=2;
    a[1]=3;
    num=2;
    for (i=1;i<=2*n;i++)
        b[i]=0;
    for (i=3;i<=n;i+=3)
        for (j=0;j<2;j++)
        {
            x=2*(i+j)-1;
            while (b[x]==0)
            {
                a[num++]=x;
                for (k=x;k<=2*n;k+=x)
                    b[k]=1;
            }
        }
    return num;
}

關於素數,還有一些好玩的性質:

1、哥德巴赫猜想,著名的素數問題,任何一個大於4的偶數都可以拆成2個素數。

2、孿生素數問題,差為2的素數有無窮對。

3、反證法的第一個試刀案例,歐幾里得證明了世界上沒有最大的素數,這玩意沒有最大隻有更大

4、目前人類(計算機?)算出來的最大素數為2^43112609-1,一個723W+位的數字.....

相關推薦

C語言素數快速判斷建立

素數是一類很有用的數,至今為止,沒有任何人發現素數的分佈規律,也沒有人能用一個公式計算出所有的素數。但素數的判斷和建立是有法可循的。 常用方法一:優化的列舉法(效率O(n*sqrt(n))),按照素數的定義從2-列舉到SQRT(N)。方法簡單易懂,這個用於判斷可以,但是建立

C#語言常用的判斷語句循環語句

只讀 代碼示例 賦值 循環 數字 其他 do while 表達 集合 C#語言中,我們常用的判斷語句和循環語句都有哪些呢? 1、if判斷 代碼格式:if(條件1){  代碼1 }else if(條件2){  代碼2

C語言無符號數有符號數相加比較的問題

轉自https://blog.csdn.net/supreme42/article/details/6687781 看個題: #include<stdio.h> int main() { unsigned int a=6; int b=-20; printf("%d\n"

C語言的淺拷貝深拷貝

淺拷貝 首先看下面這段程式碼: # include<assert.h> # include<string.h> #include <stdlib.h> typedef struct Node//定義了一個結構體 { int size; char *da

C語言的隨機數 srand ( ) rand ( )

在C語言中,生成一個隨機數,一般利用兩個函式,即void srand ( unsigned int seed ) 和 int rand ( void )。     srand() 函式用於生成一個隨機數種子,種子的值等於引數seed,這個引數由我們指定一個

C語言的單引號雙引號的區別

  首先肯定地說,二者是有區別的,不是說用誰都一樣。 1、實質區別,代表的含義不同 'A'代表的是一個整數,而且這個整數對應的是編譯器所採用的字符集中的字元序列對應的數值。所以'A'跟ASCII中的65意義是相同的。 1 # include <iostream>

C語言的指標陣列陣列指標

可以將 *string看成陣列 a[] 下的a,即指標是指向陣列的首地址的; 指標陣列是陣列元素為指標的陣列(例如 int *p[3],定義了p[0],p[1],p[2]三個指標),其本質為陣列。 指

C語言宣告、定義初始化的區別

函式和變數(全域性變數)都有宣告和定義, 對於函式而言: 同一檔案內,如果函式fun_1呼叫fun_2時,如果fun_2在fun_1之後定義,則需在fun_1之前對fun_2進行宣告,如下: void fun_2();// 宣告 void fun_1() { ... fu

C 語言的結構體共用體(聯合體)

本文主要總結了譚浩強主編的《C 程式設計》教材中結構體和共用體相關章節的內容。 在 C 語言中, 結構體(struct) 是一個或多個變數的集合,這些變數可能為不同的型別,為了處理的方便而將這些變數組織在一個名字之下。由於結構體將一組相關變數看作一個單元而不是各自獨立的實體,因此結構體有助於組織複雜的資料,

C語言變數的宣告定義

變數宣告和變數定義變數定義:用於為變數分配儲存空間,還可為變數指定初始值。程式中,變數有且僅有一個定義。變數宣告:用於向程式表明變數的型別和名字。定義也是宣告,extern宣告不是定義定義也是宣告:當定義變數時我們聲明瞭它的型別和名字。extern宣告不是定義:通過使用ext

C語言的靜態變數普通變數的區別

下面用程式碼說明: 一個可執行程式包括BSS段、資料段、程式碼段(文字段)。 bss segment ,data segment ,code/text segment ①BSS(Block by Start Symbol) :通常指用來存放程式中未初化的全域性變數和靜態變數

關於C語言返回區域性變數區域性指標變數

char *test1(void) { char b[10] = "abcde"; return b; } char *test1_ver2(void) { static char b[10] = "abcde"; return b; } char *test2(voi

C語言指標初始化常規運算

1. 指標初始化注意須知 <1>指標變數和普通變數一樣,外部或者靜態指標變數若未初始化,則被自動初始化為NULL,它的值為0(ASCII字元NULL的程式碼)。 <2>可以

C語言的字元變數字元常量

字元變數與字元常量定義   1.字元變數:char型別定義的變數   2.字元常量:一個字元常量代表ASCII字符集中的一個字元,在程式中用單引號把一個字元括起來作為字元常量 字元常量的表示形式   1.用字元的圖形符號表示,如:‘a’,‘y’   2.直接用十進位制的資料

C語言的子函式主函式有什麼聯絡啊?它們是怎麼編寫的?

函式定義的一般形式1.無參函式的一般形式 型別說明符 函式名() { 型別說明 語句 }  其中型別說明符和函式名稱為函式頭。 型別說明符指明瞭本函式的型別,函式的型別實際上是函式返回值的型別。 該型別說明符與第二章介紹的各種說明符相同。 函式名是由使用者定義的識別符號,函式名後有一個空括號,其中無引數,但括

C語言各資料型別他們對應的最大值最小值的常量

C中各種型別的最大值最小值常量定義在”limits.h”和”float.h”中。 CHAR_MIN和CHAR_MAX分別表示有符號小整型的最小值和最大值,UCHAR_MAX表示無符號小整型的最大值; SHRT_MIN和SHRT_MAX分別表示有符號短整型的最

C語言的語法錯誤語義錯誤

語法錯誤 1:如果不遵循C語言的規則就會犯語法錯誤,它類似於英語中的語法錯誤。 例如(Bugs frustrate be can)這句英語    可以看出句子中的英語單詞都是正確的,但是沒有按照正確的順序組織句子。c的語法錯誤就是指正確的c符號放在了錯誤的位置。  那麼如何

C語言++、-- 及編譯器的貪心

C語言中的++、–即自增、自減是很令人頭疼的。 剛好看到一個問題,一起分析一下。 int i = 3; (++i) + (++i) + (++i); 你覺得這個表示式的值是多少? 如果你覺得是15,那完了,你c語言學的跟我一樣,太爛了。 我去查了一下,有說是1

關於c語言各符號的意義,以及優先順序

<1> ? x:y  類似於if語句,例如: x>9?50:100;   意思是x是否大於9 ,是的話就輸出50,不是的話就輸出100; <2>字母與數字比較大小,實際比較ASCII碼值大小,字母都大於數字。 <3>c語言中,!的作

c語言判斷數字為素數

素數只能被1和它本身整除,所以只要遍歷[ 2 , x-1 ]就好了, 函式程式碼如下: int is_s(int a){ int is_s = 1; for(int i=2;i&