UNPKG

math-theory

Version:

Mathematical Theory 质数,最大公约数,最小公倍数,整除

556 lines (543 loc) 19.9 kB
var theory = (function(){ Number.prototype.add = function(num){ return Math.round((this + num) * 1e12) / 1e12 } Number.prototype.sub = function(num){ return Math.round((this - num) * 1e12) / 1e12 } Number.prototype.mul = function(num){ return Math.round((this * num) * 1e12) / 1e12 } Number.prototype.div = function(num){ return Math.round((this / num) * 1e12) / 1e12 } String.prototype.replaceAt=function(index, character) { return this.substr(0, index) + character.toString() + this.substr(index+character.toString().length); } var _gcd = function(a,b){ //两个数的最大公约数 b = b || 0 var temp; if(parseInt(a) < parseInt(b)){ temp = a a = b b = temp } while(b != 0){ temp = a % b a = b b = temp } return a; } var _lcm = function(a,b){ //求两个数的最小公倍数 var temp temp = a * b / _gcd(a,b); //最小公倍数等于两数之积除以最大公约数 return temp } var _rd = function(t1,t2,t3){//t1为下限,t2为上限,t3为需要保留的小数位 function isNum(n){ return /^\d+$/.test(n); } if(!t1 || (! isNum(t1)) ){t1=0;} if(!t2 || (! isNum(t2)) ){t2=0;} if(!t3 || (! isNum(t3)) ){t3=0;} t3 = t3>15?15:t3; // 小数位不能大于15位 var ra = Math.random() * (t2 - t1) + t1 ,du=Math.pow(10,t3) ,ra = Math.round(ra * du) if(t3 !== 0){ //计算出不是10的倍数的数字,防止产生小数的时候末尾是0变成非小数,所以再加上一个1-9的随机数 var mr = ra % 10 === 0 ? (ra + parseInt(Math.random() *9 + 1)) : ra }else{ var mr = ra } ra = mr / du; return ra; } var _leastFactor = function(n){ if (isNaN(n) || !isFinite(n)) return NaN; if (n==0) return 0; if (n%1 || n*n<2) return 1; if (n%2==0) return 2; if (n%3==0) return 3; if (n%5==0) return 5; var m = Math.sqrt(n); for (var i=7;i<=m;i+=30) { if (n%i==0) return i; if (n%(i+4)==0) return i+4; if (n%(i+6)==0) return i+6; if (n%(i+10)==0) return i+10; if (n%(i+12)==0) return i+12; if (n%(i+16)==0) return i+16; if (n%(i+22)==0) return i+22; if (n%(i+24)==0) return i+24; } return n; } var _permutations = function(n,k){ //排列 var result = 1, i,len = arguments.length if(len === 1){ k = n } if(n < k){ throw new Error("n must bigger than k") return } for(i=n;i>(n-k);i-=1){ result *= i } return result } return { rd : _rd ,format2Latex : function(_str){ /* * 将单个非latex格式的数字转换成latex格式 */ var a = _str.toString() var reg = /(\$\{.*?\}\$)/g var latexArr = a.match(reg) if(latexArr){ a = a.replace(reg,"###") } var geo = /(#{.+}#)/g a = a.replace(geo,"~~~") var geoStr = RegExp.$1 a = a.replace(/\d+/g,function(match, contents, offset, s){ var str = '' return (str.substr(0,s) + "${" + match + "}$" + str.substr(s+match.toString().length)) }); var str = this.comma2Chinese(a) if(geoStr){ str = str.replace("~~~",geoStr) } if(latexArr){ for(var i=0;i<latexArr.length;i+=1){ var temp = latexArr[i] str = str.replace(/###/,temp) } } return str } ,comma2Chinese : function(_str){ return _str .replace(/,/g,",") .replace(/\?/g,"?") .replace(/:/g,":") .replace(/;/g,";") } ,primeFactorization : function(num){ /* * 将一个数分解质因数 * return array * */ var root = Math.sqrt(num), result = arguments[1] || [], //get unnamed paremeter from recursive calls x = 2; if(num % x){//if not divisible by 2 x = 3;//assign first odd while((num % x) && ((x = x + 2) < root)){}//iterate odds } //if no factor found then num is prime x = (x <= root) ? x : num; result.push(x);//push latest prime factor //if num isn't prime factor make recursive call //arguments.callee 递归 return (x === num) ? result : arguments.callee(num/x, result) ; } ,partNum : function(n){ /* * 把一个多位数分割成单个数字,并按照从低到高反序排列返回一个数字 * return array * */ var nArr = n.toString().split("") ,i,arr = [] for(i=0;i<nArr.length;i+=1){ arr.push(parseInt(nArr[i])) } return arr.reverse() } ,getPrimes : function(_max,_min){ /* * _max 最大范围值内的质数 * _min 最小范围,如果不传,则从1开始 * 获取一定范围内的质数 * return Array * */ var max = _max ,min = _min || 2 var sieve = [], i, j, primes = []; for (i = 2; i <= max; ++i) { if (!sieve[i]) { // i has not been marked -- it is prime primes.push(i); for (j = i << 1; j <= max; j += i) { sieve[j] = true; } } } var result = [] for(i=0;i<primes.length;i+=1){ if(primes[i] >= min){ result.push(primes[i]) } } return result; } ,checkRepeat : function(sArr,subArr){ /* * 查找一个数组中截取某部分之后可能会出现的重复key值 * sArr 要查找的数字集合 * subStr 截取字符串的方式 * return object(非重复的) * */ var i,same = {},diff = {},sameArr = [] for(i=0;i<sArr.length;i+=1){ var temp = sArr[i].toString(),key = "" for(var j=0;j<subArr.length;j+=2){ key += temp.substring(subArr[j],subArr[j+1]) } if(!same[key]){ if(diff[key]){ same[key] = temp sameArr.push(temp) sameArr.push(diff[key]) delete diff[key] }else{ diff[key] = temp } }else{ sameArr.push(temp) } } //返回唯一答案的结果集 return diff } ,diffMedian : function(_digit,_min,_max){ /* * _digit 生成几位数 * _min 从哪里开始 * _max 到哪里结束 * */ var digit = (_digit>1 && _digit<=9) ? _digit : 2 ,min = _min || 0 ,max = _max || 9 ,arr = [], i,result = "" if((max - min + 1) < digit){ throw new Error("there is not enough number") } for(i=min;i<=max;i+=1){ arr.push(i) } if(min === 0){ var frd = _rd(1,9) }else{ var frd = _rd(0,arr.length-1) } result += arr.splice(frd,1)[0] for(i=1;i<digit;i+=1){ result += arr.splice(_rd(0,arr.length-1),1) } return parseInt(result) } ,ngcd : function(_array){ /* * 接收一个数组 * 返回这个数组内的最大公约数 * return int * */ if(_array.length === 1){ return _array[0] } var x = _array.splice(_array.length-1,1)[0] //arguments.callee 递归 return _gcd(x,arguments.callee(_array)) } ,nlcm : function(_array){ /* * 接收一个数组 * 返回这个数组内的最小公倍数 * return int * */ if(_array.length === 1){ return _array[0] } var x = _array.splice(_array.length-1,1)[0] //arguments.callee 递归 return _lcm(x,arguments.callee(_array)) } ,isPrime : function(number){ if (isNaN(number) || !isFinite(number) || number % 1 || number < 2) return false; if (number == _leastFactor(number)) return true; return false; } ,toFactorPowerList : function(factors) { /* * factors Array * 数组中有重复项,然后转换成次幂关系, * return [[],[]] * */ factors.sort() var result = []; var factor = factors[0]; var count = 1; for (var i = 1; i < factors.length; i++) { if (factors[i] == factor) { count++; } else { result.push([factor, count]); factor = factors[i]; count = 1; } } result.push([factor, count]); result.sort(function(a,b){ return a[0] - b[0] }) return result; } ,permutator : function(input) { /* * input Array [1,2,3] * 数组内元素的排列问题,阶乘 * return [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] * */ var set =[]; function permute (arr, data) { var cur, memo = data || []; for (var i = 0; i < arr.length; i++) { cur = arr.splice(i, 1)[0]; if (arr.length === 0) set.push(memo.concat([cur])); permute(arr.slice(), memo.concat([cur])); arr.splice(i, 0, cur); } return set; } return permute(input); } ,getCommonDivisor : function(num){ /* * 求一个数的约数 * return array * */ var arr = []; arr.push(1); for (var i=2; i<=num/2; i++) { if(num % i == 0){ arr.push(i); } } //最后该数本身也要加入到数组去 arr.push(num); return arr; } ,float2rat : function (x) { /* * 直接将小数转化为分数 * x = 2.5 return 5/2 string * x = 2 return 2 int * * */ var tolerance = 1.0E-6; var h1=1; var h2=0; var k1=0; var k2=1; var b = x; do { var a = Math.floor(b); var aux = h1; h1 = a*h1+h2; h2 = aux; aux = k1; k1 = a*k1+k2; k2 = aux; b = 1/(b-a); } while (Math.abs(x-h1/k1) > x*tolerance); if(k1 === 1){ return h1 } return h1+"/"+k1; } ,getSimpleFraction:function(a, b , mix) {// a/b /* * 化简分数 * a:分子 * b:分母 * mix:true带分数,false假分数,默认false * */ var tempA = a, tempB = b; var result = [tempA, tempB ]; if (b % a == 0) { result = [1, b / a ]; } for (var i = 2; i < tempA; i++) { if (tempA % i == 0 && tempB % i == 0) { tempA = tempA / i; tempB = tempB / i; result = arguments.callee(tempA, tempB); break; } } if(mix==true){ result = [result[0]/result[1],result[0]%result[1],result[1]]; } return result; } ,str2Fraction:function(frac){ /* * 将带分数或假分数的字符串形式转换成假分数 * frac:分数字符串 * return:[分子,分母] */ var r = frac.match(/(\d+) +(\d+)\/(\d+)/); if(r==null){ r = frac.match(/(\d+)\/(\d+)/); } if(r==null){ return frac } var a = parseInt(r[r.length-2]); var b = parseInt(r[r.length-1]); if(r.length == 4){ a += parseInt(r[1])*b; } return [a,b]; } ,linearXY : function(a,b,c,d,e,f){ //二元一次方程 //return [1,3,4,2] 1/3 4/2 var result = []; // 消元法得出 var yUp = (c * d - a * f); var yDown = (b * d - a * e); var xUp = c * yDown - b * yUp; var xDown = a * yDown; result[0] = xUp; result[1] = xDown; result[2] = yUp; result[3] = yDown; return result } ,productTwoDimensionalArray:function(count,a,first){ /* * 分数列项 * count 长度 5 * a 递进 2 * first 起始位置 2 * return [[2,4],[4,6],[6,8],[8,10],[10,12]] * * */ var results = []; for (var i = 0; i < count; i++) { results[i] = []; for (var j = 0; j < 2; j++) { results[i][j] = i * a + j * a + first; } } return results; } ,weekdaytoChinese : function(weekday){ /* * weekday是1-7之间的数字 * return 是1到7对应的星期的中文,但是7对应的是日 * */ var weekdayInChinese,week = weekday % 7; switch (week.toString()){ case "0": weekdayInChinese = "星期日"; break; case "1": weekdayInChinese = "星期一"; break; case "2": weekdayInChinese = "星期二"; break; case "3": weekdayInChinese = "星期三" break; case "4": weekdayInChinese = "星期四"; break; case "5": weekdayInChinese = "星期五"; break; case "6": weekdayInChinese = "星期六"; break; default: weekdayInChinese = "星期日"; break; } return weekdayInChinese; } ,yearIsOrNotLeapYear:function(yearNumber){ /* * yearNumber 年份 * return 是否是闰年 0 or 1 * * */ var isOrNotLeapYear,yearDescription; if(yearNumber % 4 == 0 && yearNumber % 400 != 0) { yearDescription = "闰年"; isOrNotLeapYear = 1; } else { yearDescription = "平年"; isOrNotLeapYear = 0; } return isOrNotLeapYear; } ,num2Chinese : function(_num){ var arr = ["零","一","二","三","四","五","六","七","八","九","十"] return arr[_num] || _num } ,pointPos : function(x1,y1,x2,y2,n){ /* * 矢量与定比分点、中点公式AP:PB=n * A(x1,y1)点坐标 * B(x2,y2)点坐标 * AP:PB = n * */ return {x:(x1+n*x2)/(1+n),y:(y1+n*y2)/(1+n)} } ,permutations : _permutations//排列 ,combinations : function(n,k){ /* * C n 取 k * return int * * */ var len = arguments.length if(len === 1){ k = n } if(n < k){ throw new Error("n must bigger than k") return } var np = _permutations(n,k),kp = _permutations(k) return np.div(kp) } ,factorialProcess : function(n,k){ /* * 阶乘的中是哪几个数相乘 * return arr * * */ var arr = new Array(),len = arguments.length,i if(len === 1){ k = n } if(n < k){ throw new Error("n must bigger than k") return } for(i=n;i>(n-k);i-=1){ arr.push(i) } return arr } } }) module.exports = theory()