行业资讯网欢迎您!!!

网站收藏健康资讯网联系我们

导航菜单

根号484等于多少-程序设计-素因子分解

程序设计-素因子分解

本文介绍试除法和费马因子分解法来分解正整数的素因子

算术基本定理:每个大于1的正整数都可以被唯一地写成素数的乘积。

乘积的组成为该正整数的素因子。

例:18 = 3 ? 3 ? 2 即18的素因子为3,3,2

试除法

依次使用不超过根号n的素数p除n。如果能够整除,则p为n的素因子。将整除后的数字继续使用素数整除,直到除到1或者除到素数。

例:

42833 = 7 ? 6119

6119 = 29 ? 211

43833 = 7 ? 29 ? 211 // 43833的素因子为7,29,211

36 = 2 ? 18

18 = 2 ? 9

9 = 3 ? 3

3 = 3 ? 1 // 36的素因子为2,2,3,3

程序设计

1⃣️ 求不超过根号n的素数

先使用Math.sqrt取n的平方根squareRoot

// 求整数的整数平方根

let squareRoot = Math.floor(Math.sqrt(n));

求小于squareRoot的素数

// 从小于平方根的数里求素数

for (let i = 2; i <= squareRoot; i ) {

// 是否合数(即非素数的自然数

let isComposite = false;

for (let j = 2; j < i; j ) {

if (i % j == 0) {

isComposite = true;

break;

if (!isComposite) lessThanSquareRootPrimeNum.push(i);

求得不超过根号n的素数表lessThanSquareRootPrimeNum

2⃣️ 尝试除每一个小于平方根n的素数

能够被整除的即为素因子

let finish = false;

while(!finish) {

// 如果能被整除

if ((divisionNum % lessThanSQRTNPrimeTable[divisionPrimePoint]) == 0) {

// 如果能整除 将这个素因子放入结果

nPrimeFactorization.push(lessThanSQRTNPrimeTable[divisionPrimePoint]);

// 除数除此素数

divisionNum /= lessThanSQRTNPrimeTable[divisionPrimePoint];

} else {

// 如果不能整除 尝试下一个素数

divisionPrimePoint = 1;

// 注意 如果除数被除到1 或所有小于根号n的素数都无法除这个数 循环调节结束

if (divisionNum == 1 || divisionPrimePoint >= lessThanSQRTNPrimeTable.length) finish = true

3⃣️ 注意最后的素数

除到最后 没有可以被除的素数了 那这个除数就是素数

if (divisionPrimePoint >= lessThanSQRTNPrimeTable.length && divisionNum != 0) nPrimeFactorization.push(divisionNum)

代码实现

* @method getLessThanSQRTNPrimeTable 求小于平方根n的素数

* @params {number} n 正整数

* @return {Array<number>} lessThanSquareRootPrimeNum 小于平方根n的素数表

**/

let getLessThanSQRTNPrimeTable = (n) => {

// 求整数的整数平方根

let squareRoot = Math.floor(Math.sqrt(n));

// 比整数平方根小的素数

let lessThanSquareRootPrimeNum = [];

// 从小于平方根的数里求素数

for (let i = 2; i <= squareRoot; i ) {

// 是否合数(即非素数的自然数

let isComposite = false;

for (let j = 2; j < i; j ) {

if (i % j == 0) {

isComposite = true;

break;

if (!isComposite) lessThanSquareRootPrimeNum.push(i);

return lessThanSquareRootPrimeNum;

* @method getNPrimeFactorization 获取n的素数分解

* @params { number } 正整数

* @return { Array<number> } 素数分解

**/

let getNPrimeFactorization = (n) => {

if (n < 2) return [];

// 小于根号n的所有质数

let lessThanSQRTNPrimeTable = getLessThanSQRTNPrimeTable(n);

// 待除的素数指针

let divisionPrimePoint = 0;

// 被除数

let divisionNum = n;

// n的所有素数分解

let nPrimeFactorization = []

let finish = false;

while(!finish) {

// 如果能被整除

if ((divisionNum % lessThanSQRTNPrimeTable[divisionPrimePoint]) == 0) {

nPrimeFactorization.push(lessThanSQRTNPrimeTable[divisionPrimePoint]);

divisionNum /= lessThanSQRTNPrimeTable[divisionPrimePoint];

} else {

// 如果不能整除 尝试下一个素数

divisionPrimePoint = 1;

if (divisionNum == 1 || divisionPrimePoint >= lessThanSQRTNPrimeTable.length) finish = true

if (divisionPrimePoint >= lessThanSQRTNPrimeTable.length && divisionNum != 0) nPrimeFactorization.push(divisionNum)

return nPrimeFactorization;

console.log(getNPrimeFactorization(33776925)); // [3,5,5,7,7,7,13,101]

费马因子分解法

费马因子分解法基于引理:

如果n是一个正的奇数,那么n分解为两个正整数的积和表示成两个平方数的差是一一对应的。n = a ? b = s ^ 2 ? t ^ 2 = (s - t) ?(s t) 其中s = (a b) / 2. t = (a - b) / 2

使用费马因子分解法分解,首先向上取整根号n的数m,取m ^ 2 - n = q 如果q为完全平方数,则取q的平方根a, 如果m不是完全平方数 那么取m = m 1,重复前一步。最后n的素因子分解为(m - a)和(m a)即n = (m - a) ? (m a)

例:使用费马因子分解6077.

// 由于根号6077 < 78 所以m为78

78 ^ 2 - 6077 = 7 // 7 不是完全平方数 所以 m 1 = 79

79 ^ 2 - 6077 = 164 // 164 不是完全平方数 所以 m 1 = 80

80 ^ 2 - 6077 = 323 // 323 不是完全平方数 所以 m 1 = 81

81 ^ 2 - 6077 = 484 // 484 为完全平方数 所以 a = 根号484 = 22

得a = 22 m = 81

所以6077 = (81 - 22)(81 22) = 59 ? 103

即6077的素因子为59,103

注意:费马因子分解法仅适用于奇数。

程序设计

1⃣️ 边界判断

由于费马因子分解只适用于奇数 所以如果是偶数 则直接不处理。

2⃣️ 取平方根 1

使用Math.sqrt(n)取平方根并取整 1作为我们基础的求值数

代码实现

* @method getPrimeFactByFermat 获取素因子分解通过费马因子分解法

* @params { number } 整数 只能是奇数

* @return { Array<number> } 素因子

**/

let getPrimeFactByFermat = (n) => {

// 只处理奇数

if (n % 2 == 0) return [];

// 素数无法拆解

if (isPrimeNumber(n)) return [1, n];

// 取整数平方根

let nSQRTRoot = Math.floor(Math.sqrt(n));

let baseNumber = nSQRTRoot 1;

// 另一个素因子

let otherPrime = 0

while (otherPrime == 0) {

let diff = Math.pow(baseNumber, 2) - n;

let sqrtDiff = Math.sqrt(diff)

// 如果差为平方数

if (sqrtDiff % 1 == 0) {

otherPrime = sqrtDiff

} else {

baseNumber = 1

return [baseNumber - otherPrime, baseNumber otherPrime]

console.log(getPrimeFactByFermat(3200399)) // [1601,1999]

版权声明:本站内容由互联网用户投稿自发贡献或转载于互联网,文章观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至2024tuiguang@gmail.com举报,一经查实,本站将立刻删除。

合作:2024tuiguang@gmail.com