【C零基础详解】Part2:7-14 统计素数并求和 (20分)【循环的使用】

本题要求统计给定整数MN区间内素数的个数并对它们求和。

输入格式:

输入在一行中给出两个正整数MN(1≤MN≤500)。

输出格式:

在一行中顺序输出MN区间内素数的个数以及它们的和,数字间以空格分隔。

输入样例:

10 31

输出样例:

7 143

通过代码:

#include<stdio.h>
#include<math.h>

int prime(int x);
int main(){
    int M,N;
    scanf("%d %d", &M,&N);
    int count=0,sum=0;

    for (int i=M;i<=N;i++){
        if (prime(i)){
            sum += i;
            count++;
        }
    }
    printf("%d %d", count,sum);
    return 0;
}

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

零基础详解:

整个程序的编写思路为:

  1. 找出MN之间的所有的数。
  2. 判断是否满足条件(是素数)。
  3. 记录满足条件的数的个数以及这些数的和。
1. 基本框架

在上一篇关于输入输出的内容里,有提到过关于基本框架的事情,在此对基本框架的内容进行一些完善,具体如下:

#include <stdio.h>
int main()
{
    int M, N; //定义需要用到的变量
    int count = 0, sum = 0; //变量的初始化
    scanf("%d %d", &M, &N); //需要输入的变量
    /*函数的主体*/
    printf("%d %d", count, sum); //需要输出的变量
    return 0;
}

对于大多数的问题都有着自己的输入和输出。因此我们在搭建函数框架的时候,可以先将输入和输出的部分全部搞好,剩下我们只用关心变量之间的运算即可。

2. 找到从MN之间所有的数【for

类似这种已知起点终点要找出在起点和终点之间满足某些规律的数,用for循环是一种比较简单的方法,使用方式为:for(exp1;exp2;exp3)后加Loopbody,其中:

  • exp1 用于给Loopbody中的变量赋予初值
  • exp2 用于判定是否执行Loopbody的语句【非0时执行】
  • exp3 用于在每次执行Loopbody之后修改变量的值
  • Loopbody 为每次循环中需要执行的语句

以遍历M到N之间所有的数为例,具体使用方法如下:

#include <stdio.h>
int main()
{
    int M, N;               
    int count = 0, sum = 0; 
    scanf("%d %d", &M, &N); 
    int i; //定义循环变量i
    
    for (i = M; i <= N; i++){
        /*这里边的内容被称为Loopbody*/
    }
    //也可以在for循环中定义变量,如:for (int i = M; i <= N; i++)

    printf("%d %d", count, sum); 
    return 0;
}

其中:

  • i = M:表示iM开始
  • i <= N:表示在i <= N的时候执行Loopbody的内容
  • i++:表明每次执行完Loopbody的内容后执行语句i++

这样可以保证i取到从MN的所有的值

3 进行判定【if

在编写程序的过程中,我们常常需要达到类似“如果xxx”,“就xxx”的效果。而if函数可以实现这样的效果。if函数的使用方法为:if(exp)后加sentence,其中:

  • exp 表示判定sentence是否运行的语句【0不运行,非0运行】
  • sentence 表示如果exp为真需要执行的语句

在此题中,我们需要对所有的i进行判定,判断这个i是否为素数,具体代码如下:

#include <stdio.h>
int main()
{
    int M, N;               
    int count = 0, sum = 0; 
    scanf("%d %d", &M, &N); 
    
    int i; 
    for (i = M; i <= N; i++){
    	//利用if判定那个数(i)是否是质数
        if (prime(i)){ //如果i是质数prime(i)=1,否则prime(i)=0
        /*这里输入stence*/
        }
    }

    printf("%d %d", count, sum); 
    return 0;
}
4.1 函数的调用

由于C语言内置的函数中并不包括prime,所以我们需要自己编写和调用prime函数。在调用函数之前,我们需要先定义和声明函数,具体方法为

  • 函数的定义:函数类型 函数名称( 变量类型 变量名称) 后接函数体
  • 函数的声明:函数类型 函数名称( 变量类型 变量名称); 在使用前声明

prime函数为例,具体代码如下:

#include <stdio.h>

int prime(int x); //prime函数的声明
int main()
{
    int M, N;               
    int count = 0, sum = 0; 
    scanf("%d %d", &M, &N); 
    
    int i; 
    for (i = M; i <= N; i++){
    	
        if (prime(i)){ 
        /*这里输入sentence*/
        }
    }

    printf("%d %d", count, sum); 
    return 0;
}
int prime(int x) //prime函数的定义
{
/*这里输入函数体*/
}
  • prime函数只能是0或者1,所以函数类型为int
  • prime函数的作用是判断一个自然数x是否为质数,所以输入的参数类型为int
4.2 判定素数函数【prime
  • 素数:一个数,他只能被1和他本身整除。

注:1既不是素数也不是合数

因此编写的思路为:判断一个数x是否是质数,只需要对从2x-1的所有的数取余数%,如果存在余数为0的情况,则说明x不是质数。【稍微优化一下可以只对2sqrt(x)取余数即可】

为什么 x \sqrt{x} x 证明如下:
x x x不是质数,也就是说
∀ m , n → x = m × n \forall m,n \rightarrow x = m \times n m,nx=m×n
且假设 m ≤ n m\leq n mn:两个数,总有一个小于等于另外一个,则必有:
m ≤ x ≤ n m \leq \sqrt{x} \leq n mx n
反证法可知,若 m , n < x m,n < \sqrt{x} m,n<x , 那么 m × n < x m \times n < x m×n<x【大于同理】
故,如果 x x x不是质数,那么必定存在一个 x x x的因数 m ≤ x m \leq \sqrt{x} mx

根据上述原理我们可以编写如下程序:

int prime(int x){ //质数判定函数

    if (x==1) //如果x为1,那么x不是质数,返回0
    	return 0;
    
    //如果x大于等于2,开始遍历
    for (int i=2; i<=sqrt(x); i++)  //从2到sqrt(x) 上边解释了
    	if (x%i==0)  //如果存在余数为0的情况
    		return 0; //返回0
    return 1; //如果运行完所有的都不存在,则返回1
}
5. 计数和求和

统计满足某些条件的数的个数,以及对某些数进行累加,是C程序中很常见的小技巧。通常我们让求和的结果为sum,用count来记录个数。
只需要在满足条件的语句(即if后的sentence)中增加:

  • sum += i; 表示每当满足条件的时候sum再原本的基础上加上i
  • count++; 表示每当满足条件的时候count的值增加1

在题目中具体的代码样例如下:

#include<stdio.h>
#include<math.h> //当使用sqrt函数的需要调用<math.h>

int prime(int x);
int main(){
    int M,N;
    scanf("%d %d", &M,&N);
    int count=0,sum=0;

    for (int i=M;i<=N;i++){
        if (prime(i)){ 	//如果i是素数
            sum += i; 	//sum在原本的值上+i
            count++;	//count的数量+1
        }
    }
    printf("%d %d", count,sum);
    return 0;
}

int prime(int x){
    if (x==1) return 0;
    for (int i=2; i<=sqrt(x); i++) 
    	if (x%i==0) 
    		return 0;
    return 1;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值