美文网首页
C语言笔记04_判断一个数是否为质数

C语言笔记04_判断一个数是否为质数

作者: flamingocc | 来源:发表于2018-05-18 09:08 被阅读0次

    C语言 笔记04

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

    1.程序的3种结构
    程序在执行时有几种结构,三种:

    1. 自上而下执行——顺序执行
    2. 判断条件执行——选择执行
    3. 循环条件执行——循环执行

    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.逻辑挑战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循环来解决:

    我的改进01:

    int a,i;
    a=5;     
    f=0;
    for(i=2,i<=4,i++)  // i总比a小1
    {
        if a%i==0
            printf("合数");
        else
            printf("质数");
    }
    

    输出:

    质数质数质数
    

    发现问题:如果这样写,那如果我们要判断一个很大的数比如1000,那么就会打印出998个……

    我的改进02:

    引入一个新的量f,用f的两个值来对应合数和质数:

    f 质or合
    0 质数
    1 合数

    加入for循环,循环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不是质数啊!回头看看才发现for循环中if虽然起到了判断合数的作用,但由于处于循环之中,6要除以2、3、4、5,那么for循环中f的值的变化为:

    1 1 0 0
    

    即最后6/5!=0,所以f=0,判断为质数。这是程序设计上的错误,错误为:虽然我们要对所有的a-2个数都判断,但对于不能被整除的我们不必加入else条件,for循环中只需要存在一个if条件即可。换言之,只需要找到一个余数为0的值,对于余数不为0的值我们不需要在for循环中提到!

    我的改进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就能达到以下目的:遇到第一个合数,马上退出当前循环。

    #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;    //退出循环
            }
        }
        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;  //退出循环
        printf("%d",i);
    }
    

    输出:

    12345
    

    也就是说当i为6时,直接退出循环,而不会执行for循环中后面的语句printf("%d",i);

    5.continue

    提到break就要想到continue啦!那么continue的作用是什么呢?
    continue:跳过后面语句直接进入下一轮循环

    例子:打印100内的所有偶数

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

    6.逻辑挑战8:验证哥德巴赫猜想

    本节我觉得书本中讲得很好,就不用自己的话来描述了,可以回头复习复习。


    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; }
                // 打印这个解并跳出循环
            }
        }
    }
    

    《啊哈C》:这里只验证了4到100的数,当然你可以验证更大的范围。当然,去验证哥德巴赫猜想有很多种方法,显然这种方法是不够好的,判断质数的部分也不够快,这里只是提供一种思路,等你看完了第6章再回头过来看,我想你一定可以找到更高效的方法。

    7.逻辑挑战9:水仙花数

    有一种三位数特别奇怪,这种数的“个位数的立方”加上“十位数的立方”再加上“百位数的立方”恰好等于这个数。例如:153=1×1+5×5+3×3,我们为这种特殊的三位数起了一个很好听的名字——“水仙花数”,那么请你找出所有的“水仙花数”吧。

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

    首先用3个循环嵌套打印出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循环i中只嵌套了一个for循环j;
    for循环j中只嵌套了一个for循环k;
    for循环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.逻辑挑战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.逻辑挑战11:猜数游戏
    游戏规则:计算机随机给出0~99之间的一个整数,你能否猜出这个数?每猜一
    次,计算机都会告诉你猜的大了还是小了,直到你猜出这个数为止。





    思考:

    如何生成一个1~20000000的数?


    10.逻辑挑战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次机会,请继续。\n",sum);
            if(b<a)
                printf("小了,还有%d次机会,请继续。\n",sum);
            if(b==a)
            {
                printf("恭喜你,答对了!\n");
                break;
            }
            if (sum == 0)
            {
                printf("没有机会了,系统将在60s内关机!\n");
                system("shutdown -s -t 50");
                break;
            }
        }
        system("pause");
        return 0;
    }
    

    对了,还有一个取消关机的命令:
    system("shutdown -a");

    相关文章

      网友评论

          本文标题:C语言笔记04_判断一个数是否为质数

          本文链接:https://www.haomeiwen.com/subject/qmpwdftx.html