有關(guān)質(zhì)數(shù)的一些算法及C語言實(shí)現(xiàn)

質(zhì)數(shù):質(zhì)數(shù)又稱素?cái)?shù)。一個(gè)大于1的自然數(shù)摹蘑,除了1和它自身外筹燕,不能被其他自然數(shù)整除的數(shù)叫做質(zhì)數(shù);否則稱為合數(shù)纹蝴。

問題一:給定一個(gè)整數(shù)N庄萎,找出小于N的質(zhì)數(shù),從小到大打印出來
思路:
1塘安、試除法
試除法就是不斷地嘗試能否整除糠涛。比如要判斷自然數(shù) x 是否質(zhì)數(shù),就不斷嘗試小于 x 且大于1的自然數(shù)兼犯,只要有一個(gè)能整除忍捡,則 x 是合數(shù);否則切黔,x 是質(zhì)數(shù)砸脊。
試除法的關(guān)鍵就是如何減少試除的次數(shù),需要考慮幾個(gè)點(diǎn):
一是除了2之外纬霞,其余的質(zhì)數(shù)只可能是奇數(shù)
二是對(duì)于一個(gè)數(shù)而言凌埂,其因數(shù)一定是成對(duì)出現(xiàn)的,其中一個(gè)因數(shù)大于該數(shù)的平方根诗芜,另一個(gè)因數(shù)小于該數(shù)的平方根瞳抓,因此試除的次數(shù)只要從2遍歷到該數(shù)的平方根加1即可(加1是因?yàn)榭紤]到開方后是小數(shù)埃疫,主要是3這個(gè)邊界情況)。
2孩哑、篩選法
首先栓霜,2是公認(rèn)最小的質(zhì)數(shù),所以横蜒,先把所有2的倍數(shù)去掉胳蛮;然后剩下的那些大于2的數(shù)里面,最小的是3丛晌,所以3也是質(zhì)數(shù)仅炊;然后把所有3的倍數(shù)都去掉,剩下的那些大于3的數(shù)里面茵乱,最小的是5茂洒,所以5也是質(zhì)數(shù)……
上述過程不斷重復(fù)孟岛,就可以把某個(gè)范圍內(nèi)的合數(shù)全都除去(就像被篩子篩掉一樣)瓶竭,剩下的就是質(zhì)數(shù)了。

/方法一:試除法
void find_prime_1(int num)
{
    int* prime = (int*)malloc(sizeof(int) * num);
    if(num < 2)
    {
        printf("輸入數(shù)據(jù)有誤渠羞,質(zhì)數(shù)至少要大于1斤贰!\n");
        return;
    }
    int i = 0, j = 0, k = 0;
    if(num == 2)
    {
        printf("%d", num);
    }
    else
    {
        prime[k++] = 2;
        for(i = 3; i <= num; i++)
        {
            //printf("sqrt = %d", (int)sqrt(i)+1);
            if(i % 2 == 0)
                continue;
            for(j = 2; j <= (int)sqrt(i) + 1; j++)
            {
                if(i % j == 0)
                    break;

                if(j == (int)sqrt(i) + 1)
                    prime[k++] = i;
            }
        }
    }

    for(i = 0; i < k; i++)
    {
        printf("%d ", prime[i]);
    }
    printf("\n");

}

//方法二:篩選法
void find_prime_2(int num)
{
    int* prime = (int*)malloc(sizeof(int) * (num + 1));
    //memset(prime, 1, sizeof(prime));
    int i = 0, j = 0;
    //printf("length = %d\n", sizeof(prime) / sizeof(int));
    for(i = 0; i < num + 1; i++)
    {
        if(i < 2)
            prime[i] = 0;
        else
            prime[i] = 1;
    }

    for(i = 2; i < num + 1; i++)
    {
        if(prime[i])
        {
            printf("%d ", i);
            for(j = i + i; j < num + 1;j = j + i)
            {
                prime[j] = 0;
            }
        }

    }

    printf("\n");
}
篩選法的時(shí)間復(fù)雜度要遠(yuǎn)低于試除法,當(dāng)輸入的數(shù)字是1000000時(shí)次询,試除法的運(yùn)行時(shí)間為14.526s荧恍,而篩選法的運(yùn)行時(shí)間僅為8.696s

問題二:給定一個(gè)整數(shù)N,找出自然數(shù)中最小的N個(gè)質(zhì)數(shù)屯吊,從小到大打印出來
算法思路:設(shè)計(jì)一個(gè)計(jì)數(shù)變量來控制程序運(yùn)行是否結(jié)束送巡,該計(jì)數(shù)變量用于存儲(chǔ)已經(jīng)找出的質(zhì)數(shù)的個(gè)數(shù),此外還需要設(shè)計(jì)一個(gè)函數(shù)用于判斷一個(gè)數(shù)是否是質(zhì)數(shù)

int isprime(int num)
{
    int i = 0;

    if(num < 2)
        return 0;

    if(num == 2)
        return 1;
    else
    {
        for(i = 2; i <= (int)sqrt(num) + 1; i++)
        {
            if(num % i == 0)
                return 0;

            if(i == (int)sqrt(num) + 1)
                return 1;
        }
    }
}

/*給定一個(gè)整數(shù)N盒卸,找出自然數(shù)中最小的N個(gè)質(zhì)數(shù)骗爆,從小到大打印出來*/
void find_prime_3(int num)
{
    int count = 0;
    int i = 0;
    for(i = 2; ; i++)
    {
        if(isprime(i))
        {
            count++;
            if(count > num)
                break;
            else
                printf("%d ", i);
        }
    }
    printf("\n");

}

問題3:給定一個(gè)數(shù),求出它的所有質(zhì)數(shù)因子蔽介,例如180 = 2 * 2 * 3 * 3 * 5
算法思路:一個(gè)數(shù)的因數(shù)摘投,除了質(zhì)數(shù)之外,其余的數(shù)均還存在因數(shù)虹蓄,可以通過前面已經(jīng)找到的質(zhì)數(shù)因子排除掉能被質(zhì)數(shù)因子整除的其他因子

/*給定一個(gè)數(shù)犀呼,求出它的所有質(zhì)數(shù)因子,例如180 = 2 * 2 * 3 * 3 * 5*/
void find_prime_gradient(int num)
{
    int i = 0;
    for(i = 2; i <= num; i++)  //邊界情況薇组,輸入值就是一個(gè)質(zhì)數(shù)本身外臂,那么輸出就是它本身
    {
        while(num % i == 0)
        {
            printf("%d ", i);
            num = num / i;  //排除掉后面存在能被i整除的非質(zhì)數(shù)因子
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市律胀,隨后出現(xiàn)的幾起案子宋光,更是在濱河造成了極大的恐慌挑童,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跃须,死亡現(xiàn)場(chǎng)離奇詭異站叼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)菇民,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門尽楔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人第练,你說我怎么就攤上這事阔馋。” “怎么了娇掏?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵呕寝,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我婴梧,道長(zhǎng)下梢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任塞蹭,我火速辦了婚禮孽江,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘番电。我一直安慰自己岗屏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布漱办。 她就那樣靜靜地躺著这刷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪娩井。 梳的紋絲不亂的頭發(fā)上暇屋,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音撞牢,去河邊找鬼率碾。 笑死,一個(gè)胖子當(dāng)著我的面吹牛屋彪,可吹牛的內(nèi)容都是我干的所宰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼畜挥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼仔粥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤躯泰,失蹤者是張志新(化名)和其女友劉穎谭羔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體麦向,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘟裸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了诵竭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片话告。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖卵慰,靈堂內(nèi)的尸體忽然破棺而出沙郭,到底是詐尸還是另有隱情,我是刑警寧澤裳朋,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布病线,位于F島的核電站,受9級(jí)特大地震影響鲤嫡,放射性物質(zhì)發(fā)生泄漏送挑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一泛范、第九天 我趴在偏房一處隱蔽的房頂上張望让虐。 院中可真熱鬧紊撕,春花似錦罢荡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至浪南,卻和暖如春笼才,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背络凿。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工骡送, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人絮记。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓摔踱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親怨愤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子派敷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容