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

news2024/9/24 17:14:04

前言

最近机试没少吃不会质因数分解的亏,用传统的求得因子个数只能过一点点…(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的质因数,则输出i
            cout << 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.coloradmin.cn/o/1644879.html

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

相关文章

【JavaEE网络】从数据链路层到应用层的DNS

目录 数据链路层以太网 DNS 数据链路层 越往下与程序员越远 代表协议&#xff1a;以太网。平常用的网线也叫“以太网线”&#xff0c;平常用的交换机也叫“以太网交换机” 以太网 认识以太网 “以太网” 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含…

MySql#MySql安装和配置

目录 一、卸载不需要的环境 二、安装mysql yum 源 三、开始安装 四、如果保证安装成功呢&#xff1f; 五、MySql 启动&#xff01; 六、登录mysql 七、配置文件说明 八、设置开机启动&#xff01; 本次安装是在Linux环境在centos7中完成 首先先将自己切换成root 一、…

【EI会议|稳定检索】2024年能源资源与动力、控制工程国际会议(ICERPCE 2024)

2024 International Conference on Energy Resources and Power, Control Engineering 一、大会信息 会议名称&#xff1a;2024年能源资源与动力、控制工程国际会议 会议简称&#xff1a;ICERPCE 2024 收录检索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Scholar等 会议官…

深入解析算法效率核心:时间与空间复杂度概览及优化策略

算法复杂度&#xff0c;即时间复杂度与空间复杂度&#xff0c;衡量算法运行时资源消耗。时间复杂度反映执行时间随数据规模增长的关系&#xff0c;空间复杂度表明额外内存需求。优化策略&#xff0c;如选择合适数据结构、算法改进、循环展开等&#xff0c;对于提升程序效率、减…

【高阶数据结构(一)】并查集详解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:高阶数据结构专栏⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Go语言知识   &#x1f51d;&#x1f51d; 高阶数据结构 1. 前言2. 并查集…

【vue+echarts】绘制中国地图,3D地图,省、市、县三级下钻以及回钻,南海诸岛小窗化显示,点位飞线图,点位名称弹窗轮播展示,及一些常见问题

先看效果展示图 目录 准备工作一, 绘制3D地图1,调用官网地址接口获取2,去官网下载中国地图的json数据到本地,本地引入 二, 南海诸岛小窗化显示1, 手动过滤掉,只保留小窗化的南海诸岛2, 代码层面过滤掉,只保留小窗化的南海诸岛 三, 省、市、县三级地图下钻及回钻1, 下钻2, 回钻…

深度学习 --- stanford cs231学习笔记(一)

stanford cs231学习笔记(一) 1&#xff0c;先是讲到了机器学习中的kNN算法&#xff0c;然后因为kNN分类器的一些弊端&#xff0c;引入了线性分类器。 kNN算法的三大弊端&#xff1a; (1)&#xff0c;计算量大&#xff0c;当特征比较多时表示性差 (2)&#xff0c;训练时耗时少…

C++初阶之模板初阶

一、泛型编程 如何实现一个通用的交换函数呢&#xff1f; void Swap(int& left, int& right) {int temp left;left right;right temp; } void Swap(double& left, double& right) {double temp left;left right;right temp; } void Swap(char& left,…

sql编写规范(word原件)

编写本文档的目的是保证在开发过程中产出高效、格式统一、易阅读、易维护的SQL代码。 1 编写目的 2 SQL书写规范 3 SQL编写原则 软件全套资料获取进主页或者本文末个人名片直接获取。

[Java、Android面试]_22_APP启动流程(中频问答)

欢迎查看合集&#xff1a; Java、Android面试高频系列文章合集 本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&am…

偏微分方程算法之混合边界条件下的差分法

目录 一、研究目标 二、理论推导 三、算例实现 四、结论 一、研究目标 我们在前几节中介绍了Poisson方程的边值问题&#xff0c;接下来对椭圆型偏微分方程的混合边值问题进行探讨&#xff0c;研究对象为&#xff1a; 其中&#xff0c;为矩形区域&#xff0c;为上的连续函数…

毕业设计参考-PyQt5-YOLOv8-鱼头鱼尾鱼长测量程序,OpenCV、Modbus通信、YOLO目标检测综合应用

“PyQt5-YOLOv8-鱼头鱼尾鱼长测量程序”是一个特定的软件程序&#xff0c;用于通过图像处理和目标检测技术来测量鱼类的长度。 视频效果&#xff1a; 【毕业设计】基于yolo算法与传统机器视觉的鱼头鱼尾识别_哔哩哔哩_bilibili 这个程序结合了多种技术&#xff1a; 1. OpenCV…

【数据结构(邓俊辉)学习笔记】列表03——有序列表

文章目录 0. 概述1. 唯一化2. 查找2.1 实现2.2 顺序查找2.3 复杂度 0. 概述 介绍下有序列表。 若列表中所有节点的逻辑次序与其大小次序完全一致&#xff0c;则称作有序列表&#xff08;sorted list&#xff09;。为保证节点之间可以定义次序&#xff0c;依然假定元素类型T直接…

【一刷《剑指Offer》】面试题 12:打印 1 到最大的 n 位数

力扣对应题目链接&#xff1a;LCR 135. 报数 - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;打印从1到最大的n位数_牛客题霸_牛客网 (nowcoder.com) 一、《剑指Offer》内容 二、分析题目 1、暴力解法 2、用字符串模拟数字加法 首先要考虑当 n 很大时&…

Pandas层级索引

文章目录 第1关&#xff1a;多级索引的取值与切片第2关&#xff1a;多级索引的数据转换与累计方法 第1关&#xff1a;多级索引的取值与切片 编程要求 本关的编程任务是补全右侧上部代码编辑区内的相应代码&#xff0c;要求实现如下功能&#xff1a; 使用MultiIndex创建如下Da…

Vue3+.NET6前后端分离式管理后台实战(十七)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(十七)已经在微信公众号更新&#xff0c;有兴趣的扫码关注一起交流学习。

ShardingSphere 5.x 系列【30】影子库

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 影子库与全链路压测2. 核心概念3. 使用限制4. 执行原理4.1 DML 语句4.2 D…

Vue前端环境准备

vue-cli Vue-cli是Vue官方提供的脚手架&#xff0c;用于快速生成一个Vue项目模板 提供功能&#xff1a; 统一的目录结构 本地调试 热部署 单元测试 集成打包上线 依赖环境&#xff1a;NodeJs 安装NodeJs与Vue-Cli 1、安装nodejs&#xff08;已经安装就不用了&#xff09; node-…

指挥中心操作台的选择至关重要

在指挥中心的环境中&#xff0c;操作台是核心设备&#xff0c;它承载着信息收集、处理、分发的重要任务。其选择应考虑到多方面的因素&#xff0c;包括外观、材质、稳定性、操作便利性以及技术支持等。嘉德立在这里给大家详细的总结一下选择指挥中心操作台的要点。 首先&#x…

docker挂载数据卷-以nginx为例

目录 一、什么是数据卷 二、数据卷的作用 三、如何挂载数据卷 1、创建nginx容器挂载数据卷 2、查看数据卷 3、查看数据卷详情 4、尝试在宿主机修改数据卷 5、查看容器内对应的数据卷目录 6、 访问nginx查看效果 ​​​​​​​一、什么是数据卷 挂载数据卷本质上就是实…