递归函数实现素数判断

简介: 该文介绍了素数判断的递归实现,尽管递归算法在判断素数上并不高效,时间复杂度和空间复杂度均为O(N),但作为学习和理解递归的一种方式,仍有其价值。文章强调在实际应用中应选择更高效的方法。递归思路基于试除法,对于大于1的整数,如果只能被1和自身整除,则为素数。递归函数通过不断试除2到根号下该数之间的数来判断,同时注意到偶数不是素数。文中给出了非递归和递归的试除法代码示例。

前言


素数判断是编程语言学习过程中一个老生常谈的话题,而它的实现也有多种算法,经典的试除法(以及试除法的几种优化),进阶的素数表筛选法,埃拉托斯特尼筛法和欧拉筛法(以及它们的优化)等。对以上算法感兴趣的朋友们,不妨搜索“素数判断的N种境界”来学习了解。


事实上,递归算法判断素数的本质是试除法,且递归算法在本题中并不具有优势。它不仅没有优化原算法,还增加了空间复杂度与时间复杂度。


时间复杂度和空间复杂度都是0(N),实现效率可想而知。


那为什么还要写呢?仅作为开拓思路、加深对递归函数的理解而为之。其实很多基础的算法,包括斐波那契数列、闰年等,都可以用递归实现。递归思路能将复杂的问题呈现以简单的思路,这是它的优势。通过简单问题的递归实现,大家可以提前熟悉递归的构造和运用,为后续学习数据结构“树”的相关内容作铺垫。


在实际应用中,最好还是挑选简便高效的代码实现。


题干:用递归函数判断一个自然数是否为素数。


思路简述


1. 素数:该数除了1和它本身以外不再有其他的因数(否则称为合数)。每一个比1大的整数,要么本身是一个质数,要么可以写成一系列质数的乘积。最小的质数是2。


2. 试除法


思路


1. 要判断数 i 是否为素数,由上述定义可知,需要判断除了1和它本身以外是否还有其他因数。


2. 判断方式:试除。将该数与从2到 i-1 之间所有的数除一除,看除不除得尽。若除得尽,说明该数有除了1和它本身外的其它因数,因此它就不是素数。要是除不尽,那就是素数。(该部分用递归可以实现)


3. 偶数一定不是素数,因而能被2模尽的数不是素数。


试除法参考代码如下


//试除法例题--打印100到200之间的素数
 
int main()
{
  int i = 0;
  int count = 0;
 
  for(i=101; i<=200; i+=2)    //跳过所有的偶数
  {
    //判断i是否为素数
    //2->i-1
    int j = 0;
    for(j=2; j<=sqrt(i); j++)
    {
      if(i%j == 0)
        break;
    }
 
    if(j > sqrt(i))
    {
      count++;
      printf("%d ", i);
    }
  }
 
  printf("\ncount = %d\n", count);
  return 0;
}


4. 将循环部分抽象成递归


由于每次判断素数的抽象步骤都是一样的:取模 --> 除尽了吗?(模为0吗) --> 除尽了,不是素数 --> 没除尽,接着除,全除完了还没有发现一个能除尽的 --> 是素数。


因而,改装成如下代码。


代码实现


#include<stdio.h>
 
int isPrime(int num, int divide)
{
  
  if(num == 2)    //2是最小的质数
    return 1;
  
  if(divide == 2)      //divide为2时,递归层数已经很深了
    return (num % 2 != 0);    //若(num % 2)为0,则为偶数不是素数,返回0(false);
                                  //反之返回1(true)
  
  if(num % divide == 0)
    return 0;    //如果能除尽,就不是素数
  
  else
    return isPrime(num, divide - 1);    //递归调用语句,含义是遍历从2到(num-1)中的所有数
                                            //用(divide-1)实现模数每次递减1,挨个遍历
  
}
 
int main()
{
  int num;
 
  scanf("%d", &num);
  printf("%d", isPrime(num, num - 1));
  
  return 0;
}



相关文章
|
编译器 C++
C++ 双冒号::开头的语法,::变量名,获取全局作用域变量
C++ 双冒号::开头的语法,::变量名,获取全局作用域变量
291 0
|
Kubernetes Cloud Native API
【云原生】kubernetes v1.18部署Metrics-Server:v0.3.6
【云原生】kubernetes v1.18部署Metrics-Server:v0.3.6
584 1
|
机器学习/深度学习 数据建模 定位技术
【数据结构】图的基本概念—无/有向图、权和网、完全图、路径与回路
【数据结构】图的基本概念—无/有向图、权和网、完全图、路径与回路
6066 0
【数据结构】图的基本概念—无/有向图、权和网、完全图、路径与回路
|
12月前
|
供应链 数据挖掘 API
1688app 商品详情接口系列(1688API)
1688作为国内知名批发采购平台,提供了一系列商品详情接口(API),助力企业和开发者获取商品基础、价格、库存及供应商信息。通过Python示例代码展示如何调用这些接口,应用场景涵盖采购决策辅助、数据分析与市场调研、电商平台整合及供应链管理系统的优化,为企业和采购商提供有力的数据支持,提升业务效率和竞争力。
429 15
|
4月前
|
传感器 算法 安全
STM32 温度 PID 控制系统实现
基于 STM32 的温度 PID 控制系统实现方案,包括硬件设计、软件编程和 PID 算法实现。
|
数据采集 存储 监控
探索数据治理的实践路径:构建高效、合规的数据生态系统
在当今这个数据驱动的时代,数据已成为企业最宝贵的资产之一,它不仅驱动着业务决策,还塑造着企业的竞争优势。然而,随着数据量的爆炸性增长和来源的多样化,如何有效管理这些数据,确保其质量、安全性及合规性,成为了企业面临的重大挑战。数据治理作为一套指导数据管理和使用的框架,其重要性日益凸显。本文将探讨推动数据治理的实践路径,旨在帮助企业构建高效、合规的数据生态系统。
|
机器学习/深度学习 自然语言处理 语音技术
FunAudioLLM 技术测评报告
FunAudioLLM 技术测评报告
|
应用服务中间件 Android开发
Server Tomcat v9.0 Server at localhost failed to start问题的解决
Server Tomcat v9.0 Server at localhost failed to start问题的解决
1465 0
|
应用服务中间件 Android开发
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
1258 0
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
|
存储 C语言
C语言:函数指针
C语言:函数指针
275 0