质因数分解(cpp实现)--一种快速求得一个数有多少个因子的黑魔法

前言

最近机试没少吃不会质因数分解的亏,用传统的求得因子个数只能过一点点…(ex, 20%)
质因数分解后,可以将因子问题转化为 集合的组合问题,因此会很快,目测是 l o g n log n logn (n是该整数的值)。



传统解法

假设输入整数的数值是n, 那么时间复杂度就是 n \sqrt{n} n , 显然数字很大时不能接受…

// 朴素方法  sqrt(n)
int calFactorNUmSimple(int num) {unordered_map<int, int> umap;umap[1] = 1;umap[num] = 1;for (int i = 2; i * i <= num; i++) {if (num % i == 0) {umap[i] = 1;umap[num / i] = 1;}}cout << "(simple)factor num: " <<  umap.size() << endl;// for (auto it: umap)//     cout << it.first << " ";// cout << endl;return umap.size();
}

多嘴一句,如果不想输出因子是啥,也不用开一个map, 直接用一个变量存一下个数就行。

int calFactorNUmSimpleJustForNum(int num) {int res = 2;for (int i = 2; i * i <= num; i++) {if (num % i == 0) {res++;if (i != num / i)res++;}}cout << "(simple)factor num: " <<  res << endl;return res;
}



质因数分解算法

没有仔细求证,目测 O ( l o g n ) O(log n) O(logn) 的时间复杂度。
该算法核心是 将一个数分成一个个质因数集合,每个值为 i 集合可以选出来 0到 umap[i] 个元素
因此构成的因子种类或者说个数就是 每个集合的个数 + 1 后 再相乘了
比如 108 = 2 2 ∗ 3 3 108 = 2^2 * 3 ^3 108=2233, 这个例子中 我们把 108 分成 两个质因数 2 和 3 的集合,他们分别有2个元素和3个元素,
那么总的因子种类就是 我们可以在 2 的集合中取 0 个(0个就是2的0次方就是1)或 1个,2个;
同理,从3的质因数集合中可以取 0个,1个, 2个,3个; 那么最终因数种类就是 ( 2 + 1 ) ( 3 + 1 ) = 12 (2+1) (3+1) = 12 (2+1)(3+1)=12

具体地,我们从 2的质因数集合中取 1个,从3的质因数集合中取2个,那么当前的因子就是 2 1 × 3 2 = 18 2^1 \times 3^2 = 18 21×32=18

int calFactorNum(int num) {unordered_map<int, int> umap; int x = num;for (int i = 2; i * i <= x; i++) {while (x % i == 0) {x /= i;umap[i]++;}}if (x > 1)  // 没除完,那么 x 本身也是一个质数umap[x]++;// 一个数分成一个个质因数集合,每个值为 i 集合可以选出来 0到umap[i]个元素// 因此构成的因子种类/个数就是  每个集合的个数 + 1 后 再相乘了int res = 1;for (auto it: umap) {// cout << "val: " << it.first << ", exp: " << it.second << endl;res *= (it.second + 1);}cout << "factor num:" << res << endl;return res;
}



lc 2521

2521. 数组乘积中的不同质因数数目
可以练练手

class Solution {
public:int distinctPrimeFactors(vector<int>& nums) {unordered_map<int, int> umap;for(auto x: nums) {// 每个数都来一次质因数分解for (int i = 2; i * i <= x; i++) {while(x % i == 0) {umap[i]++;x /= i;}}if (x > 1)umap[x]++;}return umap.size();}
};



demo完整代码

本案例完整代码 (C++11以上标准即可运行)

//分解质因子 
#include <iostream>
#include <unordered_map>
using namespace std;// 输出一下质因数分解
void tryOutputPrimeFactor(int num) {cout << num << "=";int x = num;for (int i = 2; i <= x; i++) { //循环查找判断质因数while (x % i == 0) { //若i为num的质因数,则输出icout << i;x /= i;    //对num除以i后的数求取质因数if (x != 1)//判断num是否除尽 cout << "*";}}cout << endl;
}// 朴素方法  sqrt(n)
int calFactorNUmSimple(int num) {unordered_map<int, int> umap;umap[1] = 1;umap[num] = 1;for (int i = 2; i * i <= num; i++) {if (num % i == 0) {umap[i] = 1;umap[num / i] = 1;}}cout << "(simple)factor num: " <<  umap.size() << endl;// for (auto it: umap)//     cout << it.first << " ";// cout << endl;return umap.size();
}int calFactorNUmSimpleJustForNum(int num) {int res = 2;for (int i = 2; i * i <= num; i++) {if (num % i == 0) {res++;if (i != num / i)res++;}}cout << "(simple)factor num: " <<  res << endl;return res;
}int calFactorNum(int num) {unordered_map<int, int> umap; int x = num;for (int i = 2; i * i <= x; i++) {while (x % i == 0) {x /= i;umap[i]++;}}if (x > 1)  // 没除完,那么 x 本身也是一个质数umap[x]++;// 一个数分成一个个质因数集合,每个值为 i 集合可以选出来 0到umap[i]个元素// 因此构成的因子种类/个数就是  每个集合的个数 + 1 后 再相乘了int res = 1;for (auto it: umap) {// cout << "val: " << it.first << ", exp: " << it.second << endl;res *= (it.second + 1);}cout << "factor num:" << res << endl;return res;
}int main()
{int num = 108;// calFactorNUmSimple(num);calFactorNUmSimpleJustForNum(num);calFactorNum(num);return 0;
}

output:

(simple)factor num: 12
factor num:12

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

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

相关文章

动态规划 ------ 背包问题

文章目录 1. 01 背包问题1.二维解决2. 一维优化 2. 完全背包问题1.暴力3 for.2. 二维优化3. 一维优化 3. 多重背包问题Ⅰ.1. 二维解决2. 一维优化 4. 多重背包问题Ⅱ5. 混合背包问题6. 二维费用背包问题7. 分组背包问题 背包问题是动态规划中非常典型的一些题&#xff0c;本篇文…

某站戴师兄——Excel学习笔记

1、拿到源数据第一件事——备份工作表&#xff0c;隐藏 Ctrlshift键L打开筛选 UV (Unique visitor)去重 是指通过互联网访问、浏览这个网页的自然人。访问网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。一天内同个访客多次访问仅计算一个UV。 PV …

进程与线程(进程)

进程&#xff1a; 概念&#xff1a;进程是进程实体的运行过程&#xff0c;是系统进行资源分配和调度的一个独立单位 PID:当进程被创建时&#xff0c;操作系统会为该进程分配一个唯一的、不重复的“身份证号” 组成&#xff1a; PCB&#xff08;进程控制块&#xff09;&#…

芋道源码的Springboot 项目打包,配置和依赖包分开

Springboot 项目&#xff0c;把依赖包和开发的应用都打在一个jar 里很简单&#xff0c;但有个问题是&#xff0c;修改点东西就要再次全量更新。 这里介绍如何用assembly 来实现不打依赖包。 1、 在主模块中&#xff0c;需要引入 assembly.xml配置&#xff1a; src/main/asse…

我这次没有蹭Oracle发布热度的原因

这次没有去蹭热度&#xff0c;原因有几个。 主观 确实是生病了&#xff0c;身体不舒服&#xff0c;那几个卷王在卷公众号的时候&#xff0c;我在床上卷成一团。 不和这几个打了鸡血的人比了。我卷了一点和他们不一样的。我节日期间看到我初中同班同学发的微博。 对这个就是我…

大学生上班族必备!九个线上兼职秘籍,让你远离失业风险

互联网时代&#xff0c;兼职新风尚&#xff1a;这些靠谱兼职让你轻松增收 随着互联网技术的飞速发展&#xff0c;兼职工作已成为许多人增加收入、提升自我能力的新选择。本文将为您揭秘一些适合大学生和上班族的靠谱兼职工作&#xff0c;助您轻松找到适合自己的兼职机会。 一…

docker系列8:容器卷挂载(上)

目录 传送门 从安装redis说起 什么是容器卷挂载 操作系统的挂载 日志文件一般是"首恶元凶" 挂载命令 容器卷挂载 卷挂载命令 启动时挂载 查看挂载卷信息 容器卷管理 查看卷列表 创建容器卷 具名挂载与匿名挂载 具名挂载 传送门 docker系列1&#xff…

C++ : list类及其模拟实现

目录 一、list的介绍和使用 list的介绍 list的使用 1.list的构造 构造函数 2.list iterator 的使用 3.list capacity 4.list element access 5.list modifiers 6.list的迭代器失效 二、list的模拟实现 要点 list类模拟实现部分接口全部代码展示 一、list的介绍和使…

Docker:centos7安装docker

官网&#xff1a;https://www.docker.com/官网 文档地址 - 确认centos7及其以上的版本 查看当前系统版本 cat /etc/redhat-release- 卸载旧版本 依照官网执行 - yum安装gcc相关 yum -y install gccyum -y install gcc-c- 安装需要的软件包 yum install -y yum-utils- 设置s…

深入学习Linux内核页框回收

目录 算法 1.选择目标页 2.PFRA设计 3.反向映射 3.1.匿名页的反向映射 3.2.try_to_unmap_anon()函数 3.3.try_to_unmap_one()函数 映射页的反向映射 优先搜索树 try_to_unmap_file()函数 PFRA实现 最近最少使用(LRU)链表 在LRU链表之间移动页 mark_page_accessed(…

Android使用kts发布aar到JitPack仓库

Android使用kts发布aar到JitPack 之前做过sdk开发&#xff0c;需要将仓库上传到maven、JitPack或JCenter,但是JCenter已停止维护&#xff0c;本文是讲解上传到JitPack的方式,使用KTS语法&#xff0c;记录使用过程中遇到的一些坑.相信Groovy的方式是大家经常使用的&#xff0c;…

Java基于Spring Boot框架的课程管理系统(附源码,说明文档)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

基于Springboot的校园疫情防控系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的校园疫情防控系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

C# WCF服务(由于内部错误,服务器无法处理该请求。)

由于内部错误&#xff0c;服务器无法处理该请求。有关该错误的详细信息&#xff0c;请打开服务器上的 IncludeExceptionDetailInFaults (从 ServiceBehaviorAttribute 或从 <serviceDebug> 配置行为)以便将异常信息发送回客户端&#xff0c;或打开对每个 Microsoft .NET …

从零开始:Django项目的创建与配置指南

title: 从零开始&#xff1a;Django项目的创建与配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 后端开发 tags: DjangoWebDevPythonORMSecurityDeploymentOptimization Django简介&#xff1a; Django是一个开源的高级Python Web框架&#xff…

C语言之整形提升和算术转换

目录 前言 一、整形提升 二、算术转换 总结 前言 本文主要介绍C语言中的整形提升和算术转换的概念和意义&#xff0c;以及例题帮助理解&#xff0c;了解之后&#xff0c;我们就能知道在C语言中&#xff0c;字符型变量如何计算以及如果变量的类型、字节大小不一致的情况下&am…

golang学习笔记(内存模型和分配机制)

操作系统的存储管理 虚拟内存管理 虚拟内存是一种内存管理技术&#xff0c;它允许操作系统为每个进程提供一个比实际物理内存更大的地址空间。这个地址空间被称为虚拟地址空间&#xff0c;而实际的物理内存则被称为物理地址空间。使用虚拟内存有以下几点好处&#xff1a; 内…

git 第一次安装设置用户名密码

git config --global user.name ljq git config --global user.email 15137659164qq.com创建公钥命令 输入后一直回车 ssh-keygen -t rsa下面这样代表成功 这里是公钥的 信息输入gitee 中 输入下面命令看是否和本机绑定成功 ssh -T gitgitee.com如何是这样&#xff0c;恭喜…

基于51单片机PWM控制直流电机—数码管显示

基于51单片机PWM控制直流电机 &#xff08;仿真&#xff0b;程序&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1.L298驱动直流电机&#xff1b; 2.数码管显示转动方向和PWM占空比&#xff08;0-100%&#xff09;&#xff1b; 3.按键控制PWM占空比来加/…

20232803 2023-2024-2 《网络攻防实践》实践八报告

目录 1. 实践内容2. 实践过程2.1 动手实践任务一2.2 动手实践任务二&#xff1a;分析Crackme程序2.2.1 crackme1.exe2.2.2 crackme2.exe 2.3 分析实践任务一2.4 分析实践任务二 3. 学习中遇到的问题及解决4. 学习感悟、思考等 1. 实践内容 动手实践任务一&#xff1a;对提供的r…