质因数分解(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,一经查实,立即删除!

相关文章

每天学习一个Linux命令之dd

每天学习一个Linux命令之dd dd命令是Linux系统下一个非常强大的工具&#xff0c;它能够进行数据的复制和转换。本文将详细介绍dd命令的使用方法及常用选项。 1. dd命令的基本介绍 dd命令是一个进行数据转换和复制的工具&#xff0c;可以从输入文件中读取数据&#xff0c;并按…

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

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

<网络安全>《74 微课堂<容器是什么?>》

1 容器 容器&#xff0c;是一种虚拟化技术。允许一个操作系统上用户空间被分割成几个独立的单元在内核中运行&#xff0c;彼此互不干扰&#xff0c;这样一个独立的空间&#xff0c;就被称之为一个容器。 2 容器技术为什么得到快速发展 随着智能制造的推进&#xff0c;企业开…

关于openEuler22.03LTS SP3尝试kolla安装容器版openstack(随手记)

遇到的问题太多了…………当然主要还是我自己能力太差了。 首先&#xff0c;官方的文档显示支持的操作系统有penEuler 22.03 LTS版本的&#xff0c;但注意&#xff1a;官方没有提供直接可用的容器镜像 官方仅提供Rocky、Debian、Ubuntu。CentOS可以使用Rocky镜像尝试&#xff0…

华为OD机试真题-可以组成网络的服务器-2023年OD统一考试(C卷D卷)

题目描述: 在一个机房中,服务器的位置标识在 n*m 的整数矩阵网格中,1 表示单元格上有服务器,0 表示没有。如果两台服务器位于同一行或者同一列中紧邻的位置,则认为它们之间可以组成一个局域网。 请你统计机房中最大的局域网包含的服务器个数。 输入描述: 第一行输入两个正…

某站戴师兄——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…

抖音直播怎么赚钱的?有多少种方法?

抖音直播确实很能挣钱&#xff0c;它一般有两种方式赚钱&#xff0c;一种是靠粉丝打赏赚钱&#xff0c;一种是在直播间卖货赚钱&#xff01; 1、抖音直播的赚钱方法一&#xff1a;粉丝打赏 主播在抖音直播&#xff0c;首先的收入来源就是靠粉丝的打赏&#xff0c;粉丝打赏的礼…