【C/C++】【基础数论】33、算数基本定理

news2024/9/27 10:54:15

算术基本定理,又称正整数的唯一分解定理。

说起来比较复杂,但是看一下案例就非常清楚了

任何一个大于 1 的正整数都可以唯一地分解成有限个质数的乘积形式,且这些质数按照从小到大的顺序排列,其指数也是唯一确定的。
例如,整数 60 可以分解为 2×2×3×5,这里的 2、3、5 都是质数,且这种分解方式是唯一的。

质数

如果一个数除了 1 和本身,没有其他的因数,就是质数。

合数

如果一个数除了 1 和本身,还有其他的因数,就是合数。

1  既不是质数,也不是合数。

一点一点过度,别着急,先看一下质数怎么判断

#include <iostream>
using namespace std;

int main()
{
    int n;
    cin >> n;
    // 初始化标志变量,默认 n 是质数
    bool flag = true; 
    for (int i = 2; i <= n; i++)
    {
        // 如果 n 能被 i 整除
        if (n % i == 0) 
        {
            // 将标志变量设为 false,表示 n 不是质数
            flag = false; 
            // 跳出循环,因为已经确定 n 不是质数了
            break; 
        }
    }
    // 根据标志变量的值输出结果
    if (flag)
    {
        cout << n << "是质数。" << endl;
    }
    else
    {
        cout << n << "不是质数。" << endl;
    }
    return 0;
}

初学者是不是都这么写,可能还不屑注释,一堆字母就完事了?

这个写法没毛病,但是执行效率可能不是很高,因为所有的数都要从2到n来除一遍。来看看,稍微升级一点的写法,

#include <iostream>
#include <cmath>
#include <limits>

int main() {
    int n;
    // 进入一个无限循环,直到输入有效为止
    while (true) {
        cout << "请输入一个正整数:";
        // 尝试读取输入到 n,如果读取成功并且 n 大于 1
        if (cin >> n && n > 1) {
            // 跳出循环,输入有效
            break;
        } else {
            // 清除输入流的错误状态标志
            cin.clear();
            // 忽略输入流中的剩余字符直到遇到换行符,防止错误输入影响后续输入
            cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            cout << "输入无效,请重新输入。" << endl;
        }
    }

    bool isPrime = true;
    // 从 2 开始循环到 n 的平方根(优化后的质数判断范围)
    for (int i = 2; i <= sqrt(n); i++) {
        // 如果 n 能被 i 整除
        if (n % i == 0) {
            // 将标志变量设为 false,表示 n 不是质数
            isPrime = false;
            // 跳出循环,因为已经确定 n 不是质数了
            break;
        }
    }

    // 根据标志变量的值输出结果
    if (isPrime) {
        cout << n << "是质数。" << endl;
    } else {
        cout << n << "不是质数。" << endl;
    }

    return 0;
}

很多人可能像我一样刚开始学的时候一样,有个疑问。sqrt是干嘛的,为啥这么写。

在这段代码中,sqrt(n)表示对变量n取算术平方根。

  1. sqrt是 C++ 标准库中<cmath>头文件里定义的一个函数,它接受一个参数并返回该参数的算术平方根。
  2. 在这个代码片段中,通过遍历从 2 到sqrt(n)的整数来判断n是否为质数。这样做的目的是优化判断质数的过程。因为如果一个数n不是质数,那么它一定存在一个小于等于sqrt(n)的因子(除了 1 和n本身)。例如,如果n = 100,那么sqrt(100)=10,在判断 100 是否为质数时,只需要检查从 2 到 10 的整数是否能整除 100 即可,而不需要检查到 99,大大减少了循环次数,提高了程序的效率。

可以这么理解,个数如果能被开平方得到一个新的整数,那么这个数一定不是质数

因为能被开平方得到整数意味着该数存在一个相同的因数与其自身相乘得到这个数,比如 9 能被开平方为 3,9 = 3×3,有除了 1 和它本身之外的因数 3,所以不是质数。

比如 41 不能被开平方得到一个整数,41 是质数。

而质数只能被 1 和它自身整除,不存在可以开平方得到但是还是质数的情况的情况。

大大减少了循环次数,提高了程序的效率。

而算术基本定理又称正整数的唯一分解定理,它不完全等同于单纯的分解质因数,但可以通过分解质因数来体现。

算术基本定理指出:任何一个大于 1 的正整数都可以唯一地分解成有限个质数的乘积形式,且这些质数按照从小到大的顺序排列,其指数也是唯一确定的。

举个例子,整数 60 可以分解为,这里的 2、3、5 都是质数,且这种分解方式是唯一的。

而分解质因数只是实现算术基本定理的一种操作手段,算术基本定理强调的是正整数分解为质数乘积的唯一性这一本质属性。

一般我们编程思想和我们数学中用到的短除法非常的类似。简单来说,短除法就是不断地用最小的质因数除以它本身。

给你一个数,你怎么快速分解出他的质因数。就用这个方法。

比如100的质因数是2*2*5*5;那我们利用短除法来求一下。

我们用代码来拆解一下

#include <iostream>
using namespace std;

int main()
{
    // 输入
    int n;
    cin >> n;

    // 输出提示信息
    cout << n << "的质因数分解为:";

    // 分解质因数
    for (int i = 2; i <= n; i++)
    {
        // 当 n 能被 i 整除时,进入循环
        while (n % i == 0)
        {
            // 输出质因数 i
            cout << i << " ";
            // 将 n 更新为 n 除以 i 的结果
            n /= i;
        }
    }
    cout << endl;
    return 0;
}

步骤说明:

  1. 首先从用户处获取一个整数n
    • int n; cin >> n;:定义变量n并读取用户输入的整数。
  2. 输出提示信息,让用户知道即将看到的是输入整数的质因数分解结果。
    • cout << n << "的质因数分解为:";:输出提示语句。
  3. i = 2开始尝试分解质因数,因为 2 是最小的质数。
    • for (int i = 2; i <= n; i++):循环从 2 开始,一直到等于n,确保所有可能的质因数都被考虑到。
  4. n能被i整除时,进入循环,不断输出i并更新n
    • while (n % i == 0):只要n能被i整除,就一直循环。
    • cout << i << " ";:输出找到的质因数i
    • n /= i;:将n更新为n除以i的结果,以便继续寻找下一个质因数。

例如,输入整数 120:

  1. 首先读取输入的 120。
  2. 输出提示信息 “120 的质因数分解为:”。
  3. i = 2开始:
    • 120 能被 2 整除,输出 2,n变为 60。
    • 60 能被 2 整除,再次输出 2,n变为 30。
    • 30 能被 2 整除,又输出 2,n变为 15。
  4. i = 3时:15 能被 3 整除,输出 3,n变为 5。
  5. i = 4不满足循环条件,继续下一个数。
  6. i = 5时:5 能被 5 整除,输出 5,此时n变为 1,循环结束。

最终输出结果为 “120 的质因数分解为:2 2 2 3 5”。

好了,有任何问题我们来评论区讨论一下吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2169756.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mvnd 初体验

https://github.com/apache/maven-mvnd/releases?page2 mvnd内嵌了Maven&#xff08;因此不需要单独安装Maven&#xff09;。mvnd客户端是通过GraalVM构建的可执行文件&#xff0c;与启动传统JVM相比&#xff0c;它的启动速度更快&#xff0c;占用的内存更少。实际构建发生在一…

【Python报错已解决】TypeError: list indices must be integers or slices, not str

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 专栏介绍 在软件开发和日常使用中&#xff0c;BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…

2.归并排序算法【分治】

步骤&#xff1a; 确定分界点&#xff0c;mid (lr)/2递归排序left、right归并&#xff0c;合二为一 package base;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class Merge_sort {static int n;static int q[];s…

TinyWebSever项目面试题整理

TinyWebSever项目面试题整理 1.为什么要做这样一个项目&#xff1f; 满足高并发和高性能需求&#xff1a;现代Web应用面对大量用户&#xff0c;Web服务器需要高效处理并发连接。比如通过线程池、非阻塞I/O、事件驱动机制&#xff08;如epoll&#xff09;&#xff0c;Web服务器…

【深度学习】(9)--调整学习率

文章目录 调整学习率一、学习率的定义二、学习率的作用三、实现调整学习率1. 使用库函数进行调整2. 手动调整学习率 总结 调整学习率 调整学习率的目的是&#xff1a;通过调整学习率&#xff0c;优化训练速度、提高训练稳定性、适应不同的训练阶段以及改善模型性能。那么&…

二维四边形网格生成算法:paving(六)行调整 Row Adjustment 与 收尾 Cleanup

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 参考论文&#xff1a;Paving: A new approach to automated quadrilateral mesh generation 关注公众号回复paving可以获得文章链接 paving&#xff08;一&#xff0…

一文讲明白初学者怎么入门大语言模型(LLM)?零基础入门到精通,收藏这篇就够了

关于如何入门LLM&#xff0c;大多数回答都提到了调用API、训练微调和应用。但是大模型更新迭代太快&#xff0c;这个月发布的大模型打榜成功&#xff0c;仅仅过了一个月就被其他模型超越。训练微调也已经不是难事&#xff0c;有大量开源的微调框架&#xff08;llamafactory、fi…

如何通过电脑控制多相机同步拍照或摄影(相机或者摄影模组数量大于60),并将所有采集的照片或视频以一定编码规则存放至规定电脑文件夹内???

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

基于Springboot+Vue的高校党建基本数据管理系统(含源码+数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…

芝法酱学习笔记(0.4)——SpringBoot多模块项目打包,resource分离,lib分离,启动脚本

前言 上期讲了如何在windows平台搭建Java后端的开发环境&#xff0c;并给出了一个简单的hello world级别的多模块代码示例。但上期仅仅是在IDEA中运行&#xff0c;和正式的生产环境完全不同。 本期将讲解&#xff0c;如何配置SpringBoot多模块项目的maven打包&#xff0c;并分…

Ubuntu22.04安装VMware Tools

目录 1. 问题2. 在线安装2.1. 更新软件源列表2.2. 更新软件2.3. 下载安装 open-vm-tools-desktop 3. 网络配置3.1 配置网络连接模式3.2 配置静态IP3.3 配置应用3.4 检查IP 1. 问题 安装好 Ubuntu 系统后&#xff0c;想要适配桌面大小等其它功能就需要安装 VMware Tools 这个工…

Linux 文件 IO 管理(第三讲:文件系统)

Linux 文件 IO 管理&#xff08;第三讲&#xff1a;文件系统&#xff09; 进程为什么默认要打开文件描述符为 0&#xff0c;1 和 2 的文件呢&#xff1f;文件系统物理磁盘简单认识存储结构对磁盘存储进行逻辑抽象分组 —— 文件系统Block Bitmapinode Tableinode BitmapGDT(Gro…

Android 利用OSMdroid开发GIS

1、地址 Github地址&#xff1a;https://gitee.com/mirrors/osmdroid Git地址&#xff1a; GitCode - 全球开发者的开源社区,开源代码托管平台 Git下载包地址&#xff1a;Releases osmdroid/osmdroid GitHub 新建项目 osmdroid在线&#xff1a; &#xff08;1&#xff09…

将Mixamo的模型和动画导入UE5

首先进入Mixamo的官网 , 点击 Character 选择一个模型 (当然你也可以自己上传模型/绑定动画) 然后点击下载 , 这个作为带骨骼的模型 选择FBX格式 , T Pose 直接下载 点击 Animations 选择动画 , 搜索 idle 默认站立动画 点击下载 , 格式选择 FBX , 不带模型只要骨骼 , 帧数选6…

低功耗TF卡:录音笔、领夹麦、电池门铃优选

概述 TF卡&#xff0c;也称为Micro SD卡或TransFlash卡&#xff0c;是一种流行的小型存储卡&#xff0c;广泛应用于手机、平板电脑、相机和其他便携式设备。TF卡的尺寸非常小&#xff0c;便于携带和使用&#xff0c;不会占用太多设备空间。而且TF卡提供多种容量选择&#xff0…

Go基础编程 - 15 - 延迟调用(defer)

延迟调用 defer 1. 特性2. 常用用途3. defer 执行顺序&#xff1a;同函数内先进后出4. defer 闭包5. defer 陷阱 上一篇&#xff1a;泛型 1. 特性 1. 关键字 defer 用于注册延迟调用。 2. defer 调用直到 return 前才被执行。 3. 同函数内多个 defer 语句&#xff0c;按先进后…

第17章 协同式任务切换

第17章 协同式任务切换 在多任务系统中&#xff0c;每个任务都有各自的局部描述符表(LDT)和任务状态段(TSS)。 从任务切换的时机来讲&#xff0c;有两种基本的策略&#xff1a; 协同式&#xff1a;从一个任务切换到另一个任务。需要当前任务主动地请求暂时放弃执行权&#x…

好看的首页展示

代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style>/* RESET…

气膜游泳馆:舒适恒温,寒冷季节中的理想游泳场所—轻空间

随着天气逐渐转凉&#xff0c;许多人在秋冬季节减少了户外活动&#xff0c;尤其是游泳。然而&#xff0c;气膜游泳馆为您提供了一种全新的选择&#xff0c;让您即使在寒冷的季节&#xff0c;也能享受畅游的乐趣。凭借其独特的恒温设计和舒适的环境&#xff0c;气膜游泳馆成为了…

计算机毕业设计宠物领养网站我的发布领养领养用户信息/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序

目录 1.课题背景 2.课题意义 ‌ 3.技术介绍 4.技术性需求 4.1后端服务‌&#xff1a; 4.2 前端展示‌ 5.数据库设计‌&#xff1a; 6.系统性能‌&#xff1a; 7.安全性‌&#xff1a; 8. 功能介绍&#xff1a; 9. 部分代码 1.课题背景 近年来&#xff0c;随着宠物饲养数量…