C語言筆記04_判斷一個數是否為質數

C語言 筆記04

本章涉及《啊哈C》第五章內容

1.程序的3種結構
程序在執(zhí)行時有幾種結構温亲,三種:

  1. 自上而下執(zhí)行——順序執(zhí)行
  2. 判斷條件執(zhí)行——選擇執(zhí)行
  3. 循環(huán)條件執(zhí)行——循環(huán)執(zhí)行

2.a++际乘,a--撩扒,a+=1

簡寫 實際意義
a++ a=a+1
a-- a=a-1
a+=2 a=a+2
a-=2 a=a-2
a*=2 a=a*2
a/=2 a=a/2
a%=2 a=a%2

還有++a,--a以后再講浴滴。

3.邏輯挑戰(zhàn)7.判斷質數很簡單

質數(素數)的定義:指大于1的自然數瘸洛,除了1和該整數自身外辰晕,無法被其他自然數整除耐薯。
合數的定義:比1大但不是質數的數顽分。

所以我們要判斷一個數字a是不是質數徐许,要將a分別除以2,3,4,……卒蘸,a-2雌隅,a-1。如果從2到a-2的所有數都不能被a整除缸沃,那么說明a為質數恰起,否則為合數。比如我們判斷5是否為質數:

  • 5%2!=0
  • 5%3!=0
  • 5%4!=0

即2 3 4 不能被5整除趾牧,所以5是一個質數检盼。

用代碼來呈現為:

int a;
a=5;
if(a%2!=0 && a%3!=0 && a%4!=0)
    printf("質數");
else
    printf("合數");

也可從反面判斷:

int a;
a=5;
if(a%2==0 || a%3==0 || a%4==0)
    printf("合數");
else
    printf("質數");

……
同樣的,我們面對較大的數字翘单,要判斷它是否為質數則會隨著數的增大而程序更加繁瑣吨枉,所以我們要改進。
比如if條件我們可以用for循環(huán)來解決:

我的改進01:

int a,i;
a=5;     
f=0;
for(i=2,i<=4,i++)  // i總比a小1
{
    if a%i==0
        printf("合數");
    else
        printf("質數")哄芜;
}

輸出:

質數質數質數

發(fā)現問題:如果這樣寫貌亭,那如果我們要判斷一個很大的數比如1000,那么就會打印出998個……

我的改進02:

引入一個新的量f认臊,用f的兩個值來對應合數和質數:

f 質or合
0 質數
1 合數

加入for循環(huán)圃庭,循環(huán)a-2次判斷a是否能整除其中某一個數,如果有失晴,則令f=1剧腻;如果沒有,則令f=0:

int a,i,f;
a=6;
for(i=2;i<=5;i++)
{
    if(a%i==0)
        f=1;
    else
        f=0;
}
if(f==0)
    printf("質數");
else
    printf("合數");

輸出:

質數

錯誤涂屁!顯然6不是質數笆樵凇!回頭看看才發(fā)現for循環(huán)中if雖然起到了判斷合數的作用胯陋,但由于處于循環(huán)之中蕊温,6要除以2袱箱、3遏乔、4义矛、5,那么for循環(huán)中f的值的變化為:

1 1 0 0

即最后6/5!=0,所以f=0盟萨,判斷為質數凉翻。這是程序設計上的錯誤,錯誤為:雖然我們要對所有的a-2個數都判斷捻激,但對于不能被整除的我們不必加入else條件制轰,for循環(huán)中只需要存在一個if條件即可。換言之胞谭,只需要找到一個余數為0的值垃杖,對于余數不為0的值我們不需要在for循環(huán)中提到!

我的改進03:

int a,f,i;
a=6;
f=0;
for(i=2;i<=5;i++)
{
    if (a%i==0)
        f=1;
}
if (f == 0)
    printf("質數\n");
else
    printf("合數\n");

輸出:

合數

正確丈屹!
完整代碼如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    a=8;
    f=0;
    for(i=2;i<=7;i++)
    {
        if (a%i==0)
            f=1;
    }
    if (f == 0)
        printf("質數\n");
    else
        printf("合數\n");
    system("pause");
    return 0;
}

升級01:輸入a判斷是否為質數

int a,f,i;
f=0;
scanf("%d",&a);
for(i=2;i<=a-1;i++)
{
    if (a%i==0)
        f=1;
}
if (f == 0)
    printf("質數\n");
else
    printf("合數\n");
system("pause");
return 0;

升級02:輸入a调俘,輸出a的所有約數和判斷a是否為質數

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    f=0;
    scanf("%d",&a);
    for(i=2;i<=a-1;i++)
    {
        if (a%i==0)
        {
            f=1;
            printf("%d",i);
        }
    }
    if (f == 0)
        printf("質數\n");
    else
        printf("合數\n");
    system("pause");
    return 0;
}

4.更快一點:break

我們可以利用break提高效率,前面我們需要判斷所有a-2個數旺垒,現在有了break就能達到以下目的:遇到第一個合數彩库,馬上退出當前循環(huán)先蒋。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,f,i;
    f=0;
    scanf("%d",&a);
    for(i=2;i<=a-1;i++)
    {
        if (a%i==0)
        {
            f=1;
            break;    //退出循環(huán)
        }
    }
    if (f == 0)
        printf("質數\n");
    else
        printf("合數\n");
    system("pause");
    return 0;
}

再舉個例子:

int i,f;
f=0;
for(i=1;i<=10;i++)
{
    if(i==6)
        break;  //退出循環(huán)
    printf("%d",i);
}

輸出:

12345

也就是說當i為6時,直接退出循環(huán)竞漾,而不會執(zhí)行for循環(huán)中后面的語句printf("%d",i);

5.continue

提到break就要想到continue啦!那么continue的作用是什么呢业岁?
continue:跳過后面語句直接進入下一輪循環(huán)

例子:打印100內的所有偶數

int a;
for(i=1;i<=100;i++)
{
    if(i%2==1)
        contine
    printf("%d",i);
}

6.邏輯挑戰(zhàn)8:驗證哥德巴赫猜想

本節(jié)我覺得書本中講得很好坦仍,就不用自己的話來描述了,可以回頭復習復習叨襟。


int k,a,b,i,fa,fb;
for(k=4;k<=100;k=k+2)
{
    for(a=2;a<=k/2;a++) 
    {
        fa=0;
        for(i=2;i<a-1;i++)  // 判斷a是否為質數
        {
            if(a%i==0) { fa=1; break;}  
        }
        if(fa==0)    // 如果a為質數
        {
            b=k-a;
            fb=0;
            for(i=2;i<b-1,i++)  // 判斷b是否為質數
            {
                if(b%i==0) { fb=1; break;}
            }
            if (fb==0)   // 如果b也是質數
            { printf("%d=%d+%d\n",k,a,b);break; }
            // 打印這個解并跳出循環(huán)
        }
    }
}

《啊哈C》:這里只驗證了4到100的數繁扎,當然你可以驗證更大的范圍。當然糊闽,去驗證哥德巴赫猜想有很多種方法梳玫,顯然這種方法是不夠好的,判斷質數的部分也不夠快右犹,這里只是提供一種思路提澎,等你看完了第6章再回頭過來看,我想你一定可以找到更高效的方法念链。

7.邏輯挑戰(zhàn)9:水仙花數

有一種三位數特別奇怪盼忌,這種數的“個位數的立方”加上“十位數的立方”再加上“百位數的立方”恰好等于這個數积糯。例如:153=1×1+5×5+3×3,我們?yōu)檫@種特殊的三位數起了一個很好聽的名字——“水仙花數”谦纱,那么請你找出所有的“水仙花數”吧看成。

法一:拼接法,列出所有可能拼出3位數

首先用3個循環(huán)嵌套打印出100~999所有三位數跨嘉,然后加入if條件判斷后打印出水仙花數:if(i100+j10+k=iii+jjj+kkk)**

int i,j,k;
for(i=1;i<=9;i++)
{
    for(j=0;j<=9;j++)
    {
        for(k=0;k<=9;k++)
        {
            if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                printf("%d%d%d\n",i,j,k);  // 可以改進:printf("%d",i*100+j*10+k);
        }
    }
}

完整代碼如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,k;
for(i=1;i<=9;i++)
{
    for(j=0;j<=9;j++)
    {
        for(k=0;k<=9;k++)
        {
            if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                printf("%d\n",i*100+j*10+k);
        }
    }
}
    system("pause");
    return 0;
}

輸出:

153
370
371
407

簡化版:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i,j,k;
    for(i=1;i<=9;i++)
        for(j=0;j<=9;j++)
            for(k=0;k<=9;k++)
                if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)
                    printf("%d\n",i*100+j*10+k);
    system("pause");
    return 0;
}

括號能夠去掉的原因:
for循環(huán)i中只嵌套了一個for循環(huán)j川慌;
for循環(huán)j中只嵌套了一個for循環(huán)k;
for循環(huán)k中只嵌套了一個if語句祠乃;
if語句中只有一個printf語句梦重,因此所有{ }都可以省略。

法二:分割法亮瓷,將要三位數x分割成a,b,c三個數

那么
百位數為→x/100
十位數為→x/10%10
個位數為→x%10

完整代碼:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int x,a,b,c;
    for(x=100;x<=999;x++)
    {
        a=x/100;
        b=x/10%10;
        c=x%10;
        if(x==a*a*a+b*b*b+c*c*c)
            printf("%d\n",x);
    }
    system("pause");
    return 0;
}

注:
這里的

        a=x/100;
        b=x/10%10;
        c=x%10;

可以改為:

        a=x/100%10
        b=x/10%10
        c=x/1%10

思考:


8.邏輯挑戰(zhàn)10:解決奧數難題

代碼如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int i;
    for(i=1;i<=9;i++)
    {
        if((i*10+3)*6528 == (30+i)*8256 )
            printf("%d\n",i);
    }
    system("pause");
    return 0;
}


輸出:


9.邏輯挑戰(zhàn)11:猜數游戲
游戲規(guī)則:計算機隨機給出0~99之間的一個整數琴拧,你能否猜出這個數?每猜一
次嘱支,計算機都會告訴你猜的大了還是小了蚓胸,直到你猜出這個數為止。





思考:

如何生成一個1~20000000的數馍盟?


10.邏輯挑戰(zhàn)12:你好壞,掛機啦

這算是本書的一個彩蛋吧贞岭,作者真的好棒!

首先介紹關機命令:

system("shutdown -s -t 50");

其中:
shutdown : 表示關機或者重啟的命令
-s : 表示關機
-t 50 : 表示在50s時關機

完整代碼:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    system("shutdown -s -t 50");
    return 0;
}

為了方便取用话速,我將它打出:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int a,b,sum;
    sum = 6;
    srand((unsigned)time(NULL));
    a = rand()%100;
    while(1)
    {
        sum--;
        scanf("%d",&b);
        if(b>a)
            printf("大了泊交,還有%d次機會柱查,請繼續(xù)。\n",sum);
        if(b<a)
            printf("小了研乒,還有%d次機會淋硝,請繼續(xù)宽菜。\n",sum);
        if(b==a)
        {
            printf("恭喜你铅乡,答對了仰楚!\n");
            break;
        }
        if (sum == 0)
        {
            printf("沒有機會了隆判,系統(tǒng)將在60s內關機!\n");
            system("shutdown -s -t 50");
            break;
        }
    }
    system("pause");
    return 0;
}

對了,還有一個取消關機的命令:
system("shutdown -a");

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末捂襟,一起剝皮案震驚了整個濱河市欢峰,隨后出現的幾起案子,更是在濱河造成了極大的恐慌宠漩,老刑警劉巖扒吁,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件室囊,死亡現場離奇詭異融撞,居然都是意外死亡,警方通過查閱死者的電腦和手機饶火,發(fā)現死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門肤寝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來急前,“玉大人裆针,你說我怎么就攤上這事寺晌∩胝鳎” “怎么了罢浇?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵攒岛,是天一觀的道長萄喳。 經常有香客問我绰垂,道長,這世上最難降的妖魔是什么凌那? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任帽蝶,我火速辦了婚禮,結果婚禮上金砍,老公的妹妹穿的比我還像新娘恕稠。我一直安慰自己扶欣,他們只是感情好料祠,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著敛苇,像睡著了一般枫攀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上来涨,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天技羔,我揣著相機與錄音,去河邊找鬼藤滥。 笑死颗味,一個胖子當著我的面吹牛浦马,可吹牛的內容都是我干的。 我是一名探鬼主播晶默,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼磺陡,長吁一口氣:“原來是場噩夢啊……” “哼币他!你這毒婦竟也來了蝴悉?” 一聲冷哼從身側響起瘾敢,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤簇抵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后晃财,有當地人在樹林里發(fā)現了一具尸體断盛,經...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡郑临,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年厢洞,在試婚紗的時候發(fā)現自己被綠了躺翻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片公你。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖迂尝,靈堂內的尸體忽然破棺而出剪芥,到底是詐尸還是另有隱情税肪,我是刑警寧澤益兄,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布锻梳,位于F島的核電站净捅,受9級特大地震影響灸叼,放射性物質發(fā)生泄漏古今。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一氓拼、第九天 我趴在偏房一處隱蔽的房頂上張望坏匪。 院中可真熱鬧,春花似錦撬统、人聲如沸适滓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凭迹。三九已至,卻和暖如春苦囱,著一層夾襖步出監(jiān)牢的瞬間嗅绸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工撕彤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鱼鸠,地道東北人。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓羹铅,卻偏偏與公主長得像蚀狰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子倒谷,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內容

  • 第一章數和數的運算 一概念 (一)整數 1整數的意義 自然數和0都是整數。 2自然數 我們在數物體的時候,用來表示...
    meychang閱讀 2,617評論 0 5
  • 【程序1】 題目:古典問題:有一對兔子,從出生后第3個月起每個月都生一對兔子,小兔子長到第三個月后每個月又生一...
    阿里高級軟件架構師閱讀 3,293評論 0 19
  • 小學奧數的知識點約 80個,總體上可以分為五大類模暗。數論和行程問題是小 學奧數學習中的重點也是難點。 一顾孽、 計算能力...
    ADolphin閱讀 7,699評論 1 3
  • (a標簽傳參問題) 1测秸、傳參 : 在遍歷商品列表的時候,直接將請求的數據(當前被點擊的商品的id,type等...
    天天向上er閱讀 293評論 0 0
  • 我聽人說,愛就大聲說出來缠俺。其實偿警,這幾年里盒使,我最后悔的事情就是告白,做的做多的事就是告解了凡泣。 一年前骂维,練車的時候航闺,認...
    ReviewPs閱讀 207評論 0 0