美文网首页
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_判断一个数是否为质数

    C语言 笔记04 本章涉及《啊哈C》第五章内容 1.程序的3种结构程序在执行时有几种结构,三种: 自上而下执行——...

  • 《Python高性能编程》札记1_判断质数

    判断一个数是否为质数:

  • 素数(质数)筛选法模板

    判断一个数是否为质数 素数筛选法(时间复杂度O(nlogn))

  • 2019-09-03

    判断一个数是否是质数 求出1-100 范围内的质数

  • 常用算法

    求最大公约数 判断字符串是否为回文串 判断数字是否为质数 判断数组中是否存在相同元素 求阶乘 二进制中1的个数

  • 如何快速的判断一个数是否是质数?

    任意的一个数,你如何能判断它是否是质数呢?我们学过的235的倍数的特点,就该想到如何判断一个数是否是质数 只要是2...

  • Numpy 求100以内质数和

    一百以内质数之和 判断是否为质数 判断一个整数是否为质数比较简单,即除了自身和1以外不可被别的数整除。不过根据数学...

  • 质数问题

    给定一个数n(n >=2),判断是否为质数 最简单的方法 若n不能被2至n-1之间的任意一个数整除则为质数 2.降...

  • Leetcode.204.Count Primes

    题目 给一个整数n,求0到n一共有多少个质数。 思路1 常规遍历,对每个数进行判断是否为质数。中间有大量重复的计算...

  • 质数判断与埃氏筛

    质数判断 我们来看这么一道问题: 给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)...

网友评论

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

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