का एक बहुत तेजी से कार्यान्वयन के लिए खोज रहे भाज्य जावास्क्रिप्ट में कार्य करते हैं। कोई सुझाव?
का एक बहुत तेजी से कार्यान्वयन के लिए खोज रहे भाज्य जावास्क्रिप्ट में कार्य करते हैं। कोई सुझाव?
जवाबों:
आप (1 ... 100) खोज सकते हैं! वुल्फरम पर | अल्फा तथ्य -क्रम की पूर्व-गणना करने के लिए।
पहले 100 नंबर हैं:
1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000, 20922789888000, 355687428096000, 6402373705728000, 121645100408832000, 2432902008176640000, 51090942171709440000, 1124000727777607680000, 25852016738884976640000, 620448401733239439360000, 15511210043330985984000000, 403291461126605635584000000, 10888869450418352160768000000, 304888344611713860501504000000, 8841761993739701954543616000000, 265252859812191058636308480000000, 8222838654177922817725562880000000, 263130836933693530167218012160000000, 8683317618811886495518194401280000000, 295232799039604140847618609643520000000, 10333147966386144929666651337523200000000, 371993326789901217467999448150835200000000, 13763753091226345046315979581580902400000000, 523022617466601111760007224100074291200000000, 20397882081197443358640281739902897356800000000, 815915283247897734345611269596115894272000000000, 33452526613163807108170062053440751665152000000000, 1405006117752879898543142606244511569936384000000000, 60415263063373835637355132068513997507264512000000000, 2658271574788448768043625811014615890319638528000000000, 119622220865480194561963161495657715064383733760000000000, 5502622159812088949850305428800254892961651752960000000000, 258623241511168180642964355153611979969197632389120000000000, 12413915592536072670862289047373375038521486354677760000000000, 608281864034267560872252163321295376887552831379210240000000000, 30414093201713378043612608166064768844377641568960512000000000000, 1551118753287382280224243016469303211063259720016986112000000000000, 80658175170943878571660636856403766975289505440883277824000000000000, 4274883284060025564298013753389399649690343788366813724672000000000000, 230843697339241380472092742683027581083278564571807941132288000000000000, 12696403353658275925965100847566516959580321051449436762275840000000000000, 710998587804863451854045647463724949736497978881168458687447040000000000000, 40526919504877216755680601905432322134980384796226602145184481280000000000000, 2350561331282878571829474910515074683828862318181142924420699914240000000000000, 138683118545689835737939019720389406345902876772687432540821294940160000000000000, 8320987112741390144276341183223364380754172606361245952449277696409600000000000000, 507580213877224798800856812176625227226004528988036003099405939480985600000000000000, 31469973260387937525653122354950764088012280797258232192163168247821107200000000000000, 1982608315404440064116146708361898137544773690227268628106279599612729753600000000000000, 126886932185884164103433389335161480802865516174545192198801894375214704230400000000000000, 8247650592082470666723170306785496252186258551345437492922123134388955774976000000000000000, 544344939077443064003729240247842752644293064388798874532860126869671081148416000000000000000, 36471110918188685288249859096605464427167635314049524593701628500267962436943872000000000000000, 2480035542436830599600990418569171581047399201355367672371710738018221445712183296000000000000000, 171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000, 11978571669969891796072783721689098736458938142546425857555362864628009582789845319680000000000000000, 850478588567862317521167644239926010288584608120796235886430763388588680378079017697280000000000000000, 61234458376886086861524070385274672740778091784697328983823014963978384987221689274204160000000000000000, 4470115461512684340891257138125051110076800700282905015819080092370422104067183317016903680000000000000000, 330788544151938641225953028221253782145683251820934971170611926835411235700971565459250872320000000000000000, 24809140811395398091946477116594033660926243886570122837795894512655842677572867409443815424000000000000000000, 1885494701666050254987932260861146558230394535379329335672487982961844043495537923117729972224000000000000000000, 145183092028285869634070784086308284983740379224208358846781574688061991349156420080065207861248000000000000000000, 11324281178206297831457521158732046228731749579488251990048962825668835325234200766245086213177344000000000000000000, 894618213078297528685144171539831652069808216779571907213868063227837990693501860533361810841010176000000000000000000, 71569457046263802294811533723186532165584657342365752577109445058227039255480148842668944867280814080000000000000000000, 5797126020747367985879734231578109105412357244731625958745865049716390179693892056256184534249745940480000000000000000000, 475364333701284174842138206989404946643813294067993328617160934076743994734899148613007131808479167119360000000000000000000, 39455239697206586511897471180120610571436503407643446275224357528369751562996629334879591940103770870906880000000000000000000, 3314240134565353266999387579130131288000666286242049487118846032383059131291716864129885722968716753156177920000000000000000000, 281710411438055027694947944226061159480056634330574206405101912752560026159795933451040286452340924018275123200000000000000000000, 24227095383672732381765523203441259715284870552429381750838764496720162249742450276789464634901319465571660595200000000000000000000, 2107757298379527717213600518699389595229783738061356212322972511214654115727593174080683423236414793504734471782400000000000000000000, 185482642257398439114796845645546284380220968949399346684421580986889562184028199319100141244804501828416633516851200000000000000000000, 16507955160908461081216919262453619309839666236496541854913520707833171034378509739399912570787600662729080382999756800000000000000000000, 1485715964481761497309522733620825737885569961284688766942216863704985393094065876545992131370884059645617234469978112000000000000000000000, 135200152767840296255166568759495142147586866476906677791741734597153670771559994765685283954750449427751168336768008192000000000000000000000, 12438414054641307255475324325873553077577991715875414356840239582938137710983519518443046123837041347353107486982656753664000000000000000000000, 1156772507081641574759205162306240436214753229576413535186142281213246807121467315215203289516844845303838996289387078090752000000000000000000000, 108736615665674308027365285256786601004186803580182872307497374434045199869417927630229109214583415458560865651202385340530688000000000000000000000, 10329978488239059262599702099394727095397746340117372869212250571234293987594703124871765375385424468563282236864226607350415360000000000000000000000, 991677934870949689209571401541893801158183648651267795444376054838492222809091499987689476037000748982075094738965754305639874560000000000000000000000, 96192759682482119853328425949563698712343813919172976158104477319333745612481875498805879175589072651261284189679678167647067832320000000000000000000000, 9426890448883247745626185743057242473809693764078951663494238777294707070023223798882976159207729119823605850588608460429412647567360000000000000000000000, 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000, 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
यदि आप अभी भी मूल्यों की गणना स्वयं करना चाहते हैं, तो आप संस्मरण का उपयोग कर सकते हैं :
var f = [];
function factorial (n) {
if (n == 0 || n == 1)
return 1;
if (f[n] > 0)
return f[n];
return f[n] = factorial(n-1) * n;
}
मैंने सोचा कि यह आलसी पुनरावृत्ति संबंधी कार्य का एक उदाहरण जोड़ने के लिए उपयोगी होगा जो तुलना के रूप में संस्मरण और कैश के साथ सटीक परिणाम प्राप्त करने के लिए बड़ी संख्या का उपयोग करता है।
var f = [new BigNumber("1"), new BigNumber("1")];
var i = 2;
function factorial(n)
{
if (typeof f[n] != 'undefined')
return f[n];
var result = f[i-1];
for (; i <= n; i++)
f[i] = result = result.multiply(i.toString());
return result;
}
var cache = 100;
// Due to memoization, following line will cache first 100 elements.
factorial(cache);
मुझे लगता है कि आप चर नाम दृश्यता को सीमित करने के लिए किसी तरह के बंद का उपयोग करेंगे ।
function factorial (n) { for (var i = f.length; i <= n; i++) f.push(f[i - 1].multiply(i.toString())); return f[n]; }
भी देखें, जो तीसरे पक्ष के पुस्तकालय के बजाय अधिक हाल के बिलिन का उपयोग करता है । BigInt
आपको एक लूप का उपयोग करना चाहिए।
यहाँ दो संस्करणों को मानदंड की गणना करके 100 के 10.000 गुना के लिए निर्धारित किया गया है।
पुनरावर्ती
function rFact(num)
{
if (num === 0)
{ return 1; }
else
{ return num * rFact( num - 1 ); }
}
चलने का
function sFact(num)
{
var rval=1;
for (var i = 2; i <= num; i++)
rval = rval * i;
return rval;
}
लाइव पर: http://jsfiddle.net/xMpTv/
मेरे परिणाम दिखाते हैं:
- पुनरावर्ती ~ 150 मिलीसेकंड
- निष्क्रिय ~ 5 मिलीसेकंड ।।
rval = rval * i;
आप लिख सकते हैंrval *= i;
मुझे अभी भी लगता है कि मार्गस का जवाब सबसे अच्छा है। हालाँकि, यदि आप 0 से 1 (यानी गामा फ़ंक्शन) के भीतर संख्याओं के भाज्य की गणना करना चाहते हैं, तो आप उस दृष्टिकोण का उपयोग नहीं कर सकते क्योंकि लुकअप तालिका में अनंत मान होंगे।
हालांकि, आप गुटों के मूल्यों को अनुमानित कर सकते हैं , और यह बहुत तेज़ है, तेज़ी से पुनरावर्ती रूप से खुद को कॉल करने या कम से कम लूप करने की तुलना में तेज़ है (विशेषकर जब मूल्य बड़े होने लगते हैं)।
एक अच्छा सन्निकटन विधि लैंकोज़ोस है
यहाँ जावास्क्रिप्ट में एक कार्यान्वयन है (एक कैलकुलेटर जिसे मैंने महीनों पहले लिखा था):
function factorial(op) {
// Lanczos Approximation of the Gamma Function
// As described in Numerical Recipes in C (2nd ed. Cambridge University Press, 1992)
var z = op + 1;
var p = [1.000000000190015, 76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 1.208650973866179E-3, -5.395239384953E-6];
var d1 = Math.sqrt(2 * Math.PI) / z;
var d2 = p[0];
for (var i = 1; i <= 6; ++i)
d2 += p[i] / (z + i);
var d3 = Math.pow((z + 5.5), (z + 0.5));
var d4 = Math.exp(-(z + 5.5));
d = d1 * d2 * d3 * d4;
return d;
}
तुम अब शांत सामान की तरह कर सकते हैं factorial(0.41)
, आदि। हालांकि सटीकता थोड़ी दूर हो सकती है, आखिरकार, यह परिणाम का एक अनुमान है।
var d3d4 = Math.exp((z + 0.5) * Math.log(z + 5.5) - z - 5.5); return d1 * d2 * d3d4;
। यह आपको 169 तक फैक्टरियल की गणना करने की अनुमति देता है! के बजाय वर्तमान में केवल 140 !. यह Number
डेटाटाइप का उपयोग करके अधिकतम प्रतिनिधित्व करने योग्य तथ्य के करीब है , जो कि 170 है!
यदि आप प्राकृतिक संख्याओं के साथ काम कर रहे हैं, तो लुकअप तालिका जाने का एक स्पष्ट तरीका है। वास्तविक समय में किसी भी तथ्यात्मक गणना करने के लिए, आप पहले से गणना की गई संख्याओं को सहेजकर, इसे कैश के साथ गति दे सकते हैं। कुछ इस तरह:
factorial = (function() {
var cache = {},
fn = function(n) {
if (n === 0) {
return 1;
} else if (cache[n]) {
return cache[n];
}
return cache[n] = n * fn(n -1);
};
return fn;
})();
इसे और अधिक गति देने के लिए आप कुछ मानों को पहले से निर्धारित कर सकते हैं।
यहाँ मेरा समाधान है:
function fac(n){
return(n<2)?1:fac(n-1)*n;
}
यह सबसे आसान तरीका है (कम वर्ण / रेखाएँ) जो मैंने पाया है, केवल एक कोड लाइन वाला एक फ़ंक्शन।
संपादित करें:
यदि आप वास्तव में कुछ चार्ट को सहेजना चाहते हैं, तो आप एरो फंक्शन (21 बाइट्स) के साथ जा सकते हैं :
f=n=>(n<2)?1:f(n-1)*n
f=n=>n?f(n-1)*n:1
...
ES6 के साथ सिर्फ एक लाइन
const factorial = n => !(n > 1) ? 1 : factorial(n - 1) * n;
factorial = n => n <= 1 ? 1 : factorial(n - 1) * n
लघु और आसान पुनरावर्ती कार्य (आप इसे लूप के साथ भी कर सकते हैं, लेकिन मुझे नहीं लगता कि प्रदर्शन में कोई अंतर होगा):
function factorial (n){
if (n==0 || n==1){
return 1;
}
return factorial(n-1)*n;
}
बहुत बड़े n के लिए, आप स्टर्लिंग के सन्निकटन का उपयोग कर सकते हैं - लेकिन यह केवल आपको अनुमानित मूल्य देगा।
संपादित करें: इस बारे में एक टिप्पणी कि मुझे इसके लिए एक नीचता क्यों मिल रही है, अच्छा रहा होगा ...
EDIT2: यह एक लूप का उपयोग करने वाली आत्मा होगी (जो बेहतर विकल्प होगा):
function factorial (n){
j = 1;
for(i=1;i<=n;i++){
j = j*i;
}
return j;
}
मुझे लगता है कि सबसे अच्छा समाधान कैश्ड मूल्यों का उपयोग करना होगा, जैसा कि मार्गस ने उल्लेख किया है और बड़े मूल्यों के लिए स्टर्लिंग के सन्निकटन का उपयोग किया है (माना कि आपको वास्तव में तेजी से होना है और ऐसी बड़ी संख्याओं पर सटीक होना जरूरी नहीं है )।
निहारना, ज्ञापनकर्ता, जो किसी एकल-तर्क फ़ंक्शन को लेता है और उसे याद करता है। कैश के आकार और संबंधित जाँच की सीमा सहित @ xPheRe के समाधान की तुलना में मामूली रूप से तेज़ हो जाता है , क्योंकि मैं शॉर्टक्रिटिंग और इतने पर उपयोग करता हूं।
function memoize(func, max) {
max = max || 5000;
return (function() {
var cache = {};
var remaining = max;
function fn(n) {
return (cache[n] || (remaining-- >0 ? (cache[n]=func(n)) : func(n)));
}
return fn;
}());
}
function fact(n) {
return n<2 ? 1: n*fact(n-1);
}
// construct memoized version
var memfact = memoize(fact,170);
// xPheRe's solution
var factorial = (function() {
var cache = {},
fn = function(n) {
if (n === 0) {
return 1;
} else if (cache[n]) {
return cache[n];
}
return cache[n] = n * fn(n -1);
};
return fn;
}());
Chrome में पुनरावर्ती संस्करण की तुलना में मेरी मशीन पर लगभग 25x तेज़ और xPheRe की तुलना में 10% अधिक तेज़ है।
मुझे लगता है कि यह लूप-आधारित संस्करण सबसे तेज़ फैक्टरियल फ़ंक्शन हो सकता है।
function factorial(n, r = 1) {
while (n > 0) r *= n--;
return r;
}
// Default parameters `r = 1`,
// was introduced in ES6
और यहाँ मेरा तर्क है:
for
लूप और while
लूप में समान प्रदर्शन होता है, एक for
लूप प्रारंभिक-अभिव्यक्ति और अंतिम-अभिव्यक्ति के बिना अजीब लगता है; शायद के for(; n > 0;)
रूप में लिखने के लिए बेहतर हैwhile(n > 0)
n
औरr
उपयोग किया जाता है, इसलिए सिद्धांत रूप में कम मापदंडों का मतलब स्मृति को आवंटित करने में कम समय खर्च करना हैn
क्या शून्य है - मैंने उन सिद्धांतों को सुना है जो बाइनरी संख्या (0 और 1) की जांच करने में बेहतर हैं, क्योंकि वे अन्य पूर्णांक की जाँच कर रहे हैंमैं इस पद पर आ गया। यहां सभी योगदानों से प्रेरित होकर मैं अपने स्वयं के संस्करण के साथ आया, जिसमें दो विशेषताएं हैं जिनके बारे में मैंने पहले चर्चा नहीं की है: 1) तर्क सुनिश्चित करने के लिए एक जांच एक गैर-नकारात्मक पूर्णांक 2 है) एक इकाई को कैश से बाहर करना फ़ंक्शन इसे एक स्वयं बनाने के लिए कोड का एक बिट समाहित करता है। मज़े के लिए, मैंने इसे यथासंभव कॉम्पैक्ट बनाने की कोशिश की। कुछ को यह सुंदर लग सकता है, दूसरे इसे बहुत अस्पष्ट समझ सकते हैं। वैसे भी, यहाँ यह है:
var fact;
(fact = function(n){
if ((n = parseInt(n)) < 0 || isNaN(n)) throw "Must be non-negative number";
var cache = fact.cache, i = cache.length - 1;
while (i < n) cache.push(cache[i++] * i);
return cache[n];
}).cache = [1];
आप या तो कैश को प्री-भर सकते हैं, या कॉल के चलते इसे भरने की अनुमति दे सकते हैं। लेकिन प्रारंभिक तत्व (तथ्य के लिए) मौजूद होना चाहिए या यह टूट जाएगा।
का आनंद लें :)
ईएस 6 का उपयोग करना बहुत सरल है
const factorial = n => n ? (n * factorial(n-1)) : 1;
एक उदाहरण यहाँ देखें
यहाँ एक समाधान है:
function factorial(number) {
total = 1
while (number > 0) {
total *= number
number = number - 1
}
return total
}
ES6 का उपयोग करके आप इसे तेज और संक्षिप्त दोनों प्राप्त कर सकते हैं:
const factorial = n => [...Array(n + 1).keys()].slice(1).reduce((acc, cur) => acc * cur, 1)
तथ्यात्मक गणना करने के लिए कोड आपकी आवश्यकताओं पर निर्भर करता है।
अंक 1 और 4 के संबंध में, लॉग का मूल्यांकन करने के लिए कार्य करना अक्सर अधिक उपयोगी होता है फैक्टरियल का न कि स्वयं फैक्टरियल का मूल्यांकन करने के लिए फ़ंक्शन के बजाय।
यहाँ एक ब्लॉग पोस्ट है जो इन मुद्दों पर चर्चा करता है। यहाँ लॉग फैक्टर की गणना के लिए कुछ C # कोड है जो जावास्क्रिप्ट में पोर्ट के लिए तुच्छ होगा। लेकिन यह ऊपर दिए गए प्रश्नों के आपके उत्तरों के आधार पर आपकी आवश्यकताओं के लिए सर्वोत्तम नहीं हो सकता है।
यह एक कॉम्पैक्ट लूप-आधारित संस्करण है
function factorial( _n )
{
var _p = 1 ;
while( _n > 0 ) { _p *= _n-- ; }
return _p ;
}
या आप मैथ ऑब्जेक्ट (पुनरावर्ती संस्करण) को ओवरराइड कर सकते हैं:
Math.factorial = function( _x ) { return _x <= 1 ? 1 : _x * Math.factorial( --_x ) ; }
या दोनों दृष्टिकोणों से जुड़ें ...
इस तथ्य को उजागर करते हुए कि Number.MAX_VALUE < 171!
, हम केवल एक पूर्ण लुकअप तालिका का उपयोग कर सकते हैं, जिसमें केवल 171 कॉम्पैक्ट सरणी तत्वों से मिलकर 1.4 किलोबाइट से कम मेमोरी ली जा सकती है।
रनटाइम कॉम्प्लेक्सिटी ओ (1) के साथ एक तेजी से लुकअप फंक्शन और ओवरहेड मिनिमम ऐक्सेस ओवरहेड इस प्रकार दिखेगा:
// Lookup table for n! for 0 <= n <= 170:
const factorials = [1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800,479001600,6227020800,87178291200,1307674368e3,20922789888e3,355687428096e3,6402373705728e3,121645100408832e3,243290200817664e4,5109094217170944e4,1.1240007277776077e21,2.585201673888498e22,6.204484017332394e23,1.5511210043330986e25,4.0329146112660565e26,1.0888869450418352e28,3.0488834461171387e29,8.841761993739702e30,2.6525285981219107e32,8.222838654177922e33,2.631308369336935e35,8.683317618811886e36,2.9523279903960416e38,1.0333147966386145e40,3.7199332678990125e41,1.3763753091226346e43,5.230226174666011e44,2.0397882081197444e46,8.159152832478977e47,3.345252661316381e49,1.40500611775288e51,6.041526306337383e52,2.658271574788449e54,1.1962222086548019e56,5.502622159812089e57,2.5862324151116818e59,1.2413915592536073e61,6.082818640342675e62,3.0414093201713376e64,1.5511187532873822e66,8.065817517094388e67,4.2748832840600255e69,2.308436973392414e71,1.2696403353658276e73,7.109985878048635e74,4.0526919504877214e76,2.3505613312828785e78,1.3868311854568984e80,8.32098711274139e81,5.075802138772248e83,3.146997326038794e85,1.98260831540444e87,1.2688693218588417e89,8.247650592082472e90,5.443449390774431e92,3.647111091818868e94,2.4800355424368305e96,1.711224524281413e98,1.1978571669969892e100,8.504785885678623e101,6.1234458376886085e103,4.4701154615126844e105,3.307885441519386e107,2.48091408113954e109,1.8854947016660504e111,1.4518309202828587e113,1.1324281178206297e115,8.946182130782976e116,7.156945704626381e118,5.797126020747368e120,4.753643337012842e122,3.945523969720659e124,3.314240134565353e126,2.81710411438055e128,2.4227095383672734e130,2.107757298379528e132,1.8548264225739844e134,1.650795516090846e136,1.4857159644817615e138,1.352001527678403e140,1.2438414054641308e142,1.1567725070816416e144,1.087366156656743e146,1.032997848823906e148,9.916779348709496e149,9.619275968248212e151,9.426890448883248e153,9.332621544394415e155,9.332621544394415e157,9.42594775983836e159,9.614466715035127e161,9.90290071648618e163,1.0299016745145628e166,1.081396758240291e168,1.1462805637347084e170,1.226520203196138e172,1.324641819451829e174,1.4438595832024937e176,1.588245541522743e178,1.7629525510902446e180,1.974506857221074e182,2.2311927486598138e184,2.5435597334721877e186,2.925093693493016e188,3.393108684451898e190,3.969937160808721e192,4.684525849754291e194,5.574585761207606e196,6.689502913449127e198,8.094298525273444e200,9.875044200833601e202,1.214630436702533e205,1.506141741511141e207,1.882677176888926e209,2.372173242880047e211,3.0126600184576594e213,3.856204823625804e215,4.974504222477287e217,6.466855489220474e219,8.47158069087882e221,1.1182486511960043e224,1.4872707060906857e226,1.9929427461615188e228,2.6904727073180504e230,3.659042881952549e232,5.012888748274992e234,6.917786472619489e236,9.615723196941089e238,1.3462012475717526e241,1.898143759076171e243,2.695364137888163e245,3.854370717180073e247,5.5502938327393044e249,8.047926057471992e251,1.1749972043909107e254,1.727245890454639e256,2.5563239178728654e258,3.80892263763057e260,5.713383956445855e262,8.62720977423324e264,1.3113358856834524e267,2.0063439050956823e269,3.0897696138473508e271,4.789142901463394e273,7.471062926282894e275,1.1729568794264145e278,1.853271869493735e280,2.9467022724950384e282,4.7147236359920616e284,7.590705053947219e286,1.2296942187394494e289,2.0044015765453026e291,3.287218585534296e293,5.423910666131589e295,9.003691705778438e297,1.503616514864999e300,2.5260757449731984e302,4.269068009004705e304,7.257415615307999e306];
// Lookup function:
function factorial(n) {
return factorials[n] || (n > 170 ? Infinity : NaN);
}
// Test cases:
console.log(factorial(NaN)); // NaN
console.log(factorial(-Infinity)); // NaN
console.log(factorial(-1)); // NaN
console.log(factorial(0)); // 1
console.log(factorial(170)); // 7.257415615307999e+306 < Number.MAX_VALUE
console.log(factorial(171)); // Infinity > Number.MAX_VALUE
console.log(factorial(Infinity)); // Infinity
यह Number
डेटाटाइप का उपयोग करते हुए जितना सटीक और उतना ही तेज़ है । जावास्क्रिप्ट में लुकअप टेबल की गणना - जैसा कि कुछ अन्य उत्तर बताते हैं - जब सटीकता कम हो जाएगी n! > Number.MAX_SAFE_INTEGER
।
Gzip के माध्यम से रनटाइम टेबल को कंप्रेस करने से डिस्क पर इसका आकार लगभग 3.6 से 1.8 किलोबाइट तक कम हो जाता है।
एक पंक्ति उत्तर:
const factorial = (num, accumulator) => num <= 1 ? accumulator || 1 : factorial(--num, num * (accumulator || num + 1));
factorial(5); // 120
factorial(10); // 3628800
factorial(3); // 6
factorial(7); // 5040
// et cetera
BigInt
सुरक्षा के लिए निष्क्रिय तथ्यसमाधान का उपयोग करता है
BigInt
, एक ईएस 2018 + / 2019 सुविधा।
यह काम कर रहे उदाहरण का उपयोग करता है BigInt
, क्योंकि यहां कई जवाब सभी Number
(एमडीएन) की सुरक्षित सीमा से लगभग दूर निकल जाते हैं। यह सबसे तेज़ नहीं है, लेकिन यह सरल है और इस प्रकार अन्य अनुकूलन (पहले 100 नंबर के कैश की तरह) को अपनाने के लिए स्पष्ट है।
function factorial(nat) {
let p = BigInt(1)
let i = BigInt(nat)
while (1 < i--) p *= i
return p
}
// 9.332621544394415e+157
Number(factorial(100))
// "933262154439441526816992388562667004907159682643816214685929638952175999
// 932299156089414639761565182862536979208272237582511852109168640000000000
// 00000000000000"
String(factorial(100))
// 9332621544394415268169923885626670049071596826438162146859296389521759999
// 3229915608941463976156518286253697920827223758251185210916864000000000000
// 000000000000n
factorial(100)
n
एक अंकीय शाब्दिक तरह के अंत में 1303n
इंगित करता है कि यह एक है BigInt
प्रकार।BigInt
के साथ Number
जब तक आप स्पष्ट रूप से उन्हें मजबूर, और ऐसा करने सटीकता में कमी का कारण बनेगा।ES6 सुविधाओं का उपयोग करते हुए, एक पंक्ति और पुनरावृत्ति के बिना कोड लिख सकते हैं :
var factorial=(n)=>Array.from({length: n},(v, k) => k+1).reduce((a, b) => a*b, 1)
पूर्णता के लिए, यहां एक पुनरावर्ती संस्करण है जो पूंछ कॉल अनुकूलन की अनुमति देगा। मुझे यकीन नहीं है अगर पूंछ कॉल अनुकूलन अनुकूलन जावास्क्रिप्ट में किया जाता है, हालांकि ..
function rFact(n, acc)
{
if (n == 0 || n == 1) return acc;
else return rFact(n-1, acc*n);
}
इसे कॉल करने के लिए:
rFact(x, 1);
यह एक पुनरावृत्त समाधान है जो कम स्टैक स्थान का उपयोग करता है और पहले-संकलित मानों को आत्म-ज्ञापन तरीके से बचाता है:
Math.factorial = function(n){
if(this.factorials[n]){ // memoized
return this.factorials[n];
}
var total=1;
for(var i=n; i>0; i--){
total*=i;
}
this.factorials[n] = total; // save
return total;
};
Math.factorials={}; // store
यह भी ध्यान दें कि मैं इसे मैथ ऑब्जेक्ट में जोड़ रहा हूं जो एक ऑब्जेक्ट शाब्दिक है ताकि कोई प्रोटोटाइप न हो। बल्कि सीधे समारोह के लिए इन बाध्यकारी।
Math.factorial(100); Math.factorial(500);
में उपप्रकारों के लिए संस्मरण का पूर्ण लाभ नहीं उठाता है - उदाहरण के लिए, दो बार 1..100 गुणा की गणना करेगा।
मेरा मानना है कि उपरोक्त टिप्पणियों में से कोड का सबसे स्थायी और कुशल टुकड़ा है। आप इसे अपने वैश्विक एप्लिकेशन js आर्किटेक्चर में उपयोग कर सकते हैं ... और, इसे कई नामस्थानों में लिखने के बारे में चिंता न करें (क्योंकि यह एक ऐसा कार्य है, जिसे शायद बहुत वृद्धि की आवश्यकता नहीं है)। मैंने 2 विधि नामों को शामिल किया है (वरीयता के आधार पर) लेकिन दोनों का उपयोग किया जा सकता है क्योंकि वे केवल संदर्भ हैं।
Math.factorial = Math.fact = function(n) {
if (isNaN(n)||n<0) return undefined;
var f = 1; while (n > 1) {
f *= n--;
} return f;
};
n * (n-1) * (n-2) * ... * 1
दूसरे तरीके के बजाय अपने गुणन को शुरू करने से, आप n> 20 के लिए परिशुद्धता में 4 अंकों तक ढीले हो जाते हैं।
// if you don't want to update the Math object, use `var factorial = ...`
Math.factorial = (function() {
var f = function(n) {
if (n < 1) {return 1;} // no real error checking, could add type-check
return (f[n] > 0) ? f[n] : f[n] = n * f(n -1);
}
for (i = 0; i < 101; i++) {f(i);} // precalculate some values
return f;
}());
factorial(6); // 720, initially cached
factorial[6]; // 720, same thing, slightly faster access,
// but fails above current cache limit of 100
factorial(100); // 9.33262154439441e+157, called, but pulled from cache
factorial(142); // 2.6953641378881614e+245, called
factorial[141]; // 1.89814375907617e+243, now cached
यह फ्लाई पर पहले 100 मानों का कैशिंग करता है, और कैश के लिए एक बाहरी चर का परिचय नहीं देता है, मानों को फ़ंक्शन ऑब्जेक्ट के गुणों के रूप में संग्रहीत करता है, जिसका अर्थ है कि यदि आप जानते हैं कि आप factorial(n)
पहले से ही गणना कर चुके हैं, तो आप कर सकते हैं बस इसके रूप में देखें factorial[n]
, जो थोड़ा अधिक कुशल है। इन 100 मानों को चलाने से आधुनिक ब्राउज़रों में उप-मिलीसेकंड समय लगेगा।
21! > Number.MAX_SAFE_INTEGER
, क्योंकि इस प्रकार सुरक्षित रूप से 64-बिट फ्लोट के रूप में प्रतिनिधित्व नहीं किया जा सकता है।
यहां एक कार्यान्वयन है जो सकारात्मक और नकारात्मक दोनों प्रकार के तथ्य की गणना करता है। यह तेज और सरल है।
var factorial = function(n) {
return n > 1
? n * factorial(n - 1)
: n < 0
? n * factorial(n + 1)
: 1;
}
यहां एक मैंने खुद बनाया है, 170 या 2 से कम संख्या का उपयोग न करें।
function factorial(x){
if((!(isNaN(Number(x)))) && (Number(x)<=170) && (Number(x)>=2)){
x=Number(x);for(i=x-(1);i>=1;--i){
x*=i;
}
}return x;
}
i
और कई Number
रूपांतरण करता है और 0 के लिए गलत परिणाम देता है! (जैसा कि आपने कहा, लेकिन क्यों?)।
यहाँ मेरा कोड है
function factorial(num){
var result = num;
for(i=num;i>=2;i--){
result = result * (i-1);
}
return result;
}
factorial(0)
। इसके अलावा, n * (n-1) * (n-2) * ... * 1 के साथ अपने गुणन को शुरू करने के बजाय दूसरे रास्ते के बजाय, आप n> 20 के लिए परिशुद्धता में 4 अंकों तक ढीले होते हैं। @prime: 170! > Number.MAX_VALUE
और के साथ सबसे अच्छा प्रतिनिधित्व किया है Infinity
।
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n)
}
द्वारा प्रदान की http://javascript.info/tutorial/number-math यदि एक वस्तु गणना के लिए एक उचित पूर्णांक है मूल्यांकन करने के लिए एक आसान तरीका के रूप में।
var factorials=[[1,2,6],3];
मेमोइज्ड फैक्टरियों का एक सरल सेट जिसमें अनावश्यक गणना की आवश्यकता होती है, "1 से गुणा" के साथ संसाधित किया जा सकता है, या एक अंक है जो एक सरल समीकरण है जो प्रसंस्करण के लायक नहीं है।
var factorial = (function(memo,n) {
this.memomize = (function(n) {
var ni=n-1;
if(factorials[1]<n) {
factorials[0][ni]=0;
for(var factorial_index=factorials[1]-1;factorials[1]<n;factorial_index++) {
factorials[0][factorials[1]]=factorials[0][factorial_index]*(factorials[1]+1);
factorials[1]++;
}
}
});
this.factorialize = (function(n) {
return (n<3)?n:(factorialize(n-1)*n);
});
if(isNumeric(n)) {
if(memo===true) {
this.memomize(n);
return factorials[0][n-1];
}
return this.factorialize(n);
}
return factorials;
});
अन्य सदस्यों से इनपुट की समीक्षा करने के बाद (लॉग सलाह को छोड़कर, हालांकि मैं इसे बाद में लागू कर सकता हूं) मैं आगे बढ़ा और एक स्क्रिप्ट को फेंक दिया जो काफी सरल है। मैंने एक साधारण अशिक्षित जावास्क्रिप्ट OOP उदाहरण के साथ शुरुआत की और factorials को संभालने के लिए एक छोटा वर्ग बनाया। फिर मैंने ऊपर दिए गए मेमोइज़ेशन के अपने संस्करण को लागू किया। मैंने शॉर्टहैंड फैक्ट्रीलाइज़ेशन भी लागू किया, हालांकि मैंने एक छोटी सी त्रुटि समायोजन की; मैंने "n <2" को "n <3" में बदल दिया। "n <2" अभी भी n = 2 को संसाधित करेगा जो एक बेकार होगा, क्योंकि आप 2 * 1 = 2 के लिए पुनरावृति करेंगे; यह मेरी राय में एक बेकार है। मैंने इसे "n <3" में बदल दिया; क्योंकि यदि n 1 या 2 है तो यह केवल n पर वापस आ जाएगा, यदि यह 3 या अधिक है तो यह सामान्य रूप से मूल्यांकन करेगा। बेशक, नियम लागू होने के बाद, मैंने अपने कार्यों को ग्रहण किए गए क्रियान्वयन के अवरोही क्रम में रखा। मैंने मेम (ईडी) और सामान्य निष्पादन के बीच त्वरित फेरबदल की अनुमति देने के लिए बूल (सच | गलत) विकल्प में जोड़ा (आप "शैली को बदलने की आवश्यकता के बिना अपने पेज पर जब आप स्वैप करना चाहते हैं, तो आप कभी नहीं जान सकते) जैसा कि मैंने पहले कहा था। ज्ञापन वाले भाज्य चर को 3 प्रारंभिक स्थितियों के साथ सेट किया जाता है, 4 वर्णों को लिया जाता है, और व्यर्थ गणनाओं को न्यूनतम किया जाता है। तीसरी पुनरावृत्ति के पूर्व का सब कुछ आप दोहरे अंकों के गणित से जोड़ रहे हैं। यदि आप इसके बारे में पर्याप्त रूप से एक स्टैक्लर लगाते हैं, तो आप यह जानेंगे कि आप एक तथ्यात्मक तालिका (जैसा लागू हो) पर चलेंगे। 4 वर्ण लेना, और व्यर्थ गणना को कम करना। तीसरी पुनरावृत्ति के पूर्व का सब कुछ आप दोहरे अंकों के गणित से जोड़ रहे हैं। यदि आप इसके बारे में पर्याप्त रूप से एक स्टैक्लर लगाते हैं, तो आप यह जानेंगे कि आप एक तथ्यात्मक तालिका (जैसा लागू हो) पर चलेंगे। 4 वर्ण लेना, और व्यर्थ गणना को कम करना। तीसरी पुनरावृत्ति के पूर्व का सब कुछ आप दोहरे अंकों के गणित से जोड़ रहे हैं। यदि आप इसके बारे में पर्याप्त रूप से एक स्टैक्लर लगाते हैं, तो आप यह जानेंगे कि आप एक तथ्यात्मक तालिका (जैसा लागू हो) पर चलेंगे।
मैंने इसके बाद क्या योजना बनाई है? स्थानीय और सत्र भंडारण, आवश्यक पुनरावृत्तियों के मामले कैश द्वारा एक मामले के लिए अनुमति देने के लिए, आवश्यक रूप से ऊपर "तालिका" समस्या को संभाल रहा है। यह बड़े पैमाने पर डेटाबेस और सर्वर साइड स्पेस को भी बचाएगा। हालाँकि, यदि आप लोकलस्टोरेज के साथ जाते हैं, तो आप अनिवार्य रूप से अपने यूजर्स के कंप्यूटर पर जगह की संख्या की एक सूची को स्टोर करने के लिए और उनके स्क्रीन को तेजी से बनाने के लिए स्पेस चूस रहे होंगे, हालांकि एक लंबे समय से अधिक समय तक इसकी जरूरत धीमी रहेगी। मुझे लगता है कि सेशनस्टोरेज (टैब पत्तियों के बाद समाशोधन) एक बेहतर मार्ग होगा। संभवतः इसे एक आत्म संतुलन सर्वर / स्थानीय निर्भर कैश के साथ संयोजित करें? उपयोगकर्ता A को X पुनरावृत्तियों की आवश्यकता है। उपयोगकर्ता B को Y पुनरावृत्तियों की आवश्यकता है। X + Y / 2 = स्थानीय रूप से कैश की गई राशि। फिर बस लोड-टाइम के साथ पता लगाना और फिडेल करना और समय-समय पर निष्पादित बेंचमार्क हर उपयोगकर्ता के लिए रहते हैं जब तक कि वह खुद को साइट के लिए ऑप्टिमाइज़ करने के लिए समायोजित नहीं करता है। धन्यवाद!
संपादित करें 3:
var f=[1,2,6];
var fc=3;
var factorial = (function(memo) {
this.memomize = (function(n) {
var ni=n-1;
if(fc<n) {
for(var fi=fc-1;fc<n;fi++) {
f[fc]=f[fi]*(fc+1);
fc++;
}
}
return f[ni];
});
this.factorialize = (function(n) {
return (n<3)?n:(factorialize(n-1)*n);
});
this.fractal = (function (functio) {
return function(n) {
if(isNumeric(n)) {
return functio(n);
}
return NaN;
}
});
if(memo===true) {
return this.fractal(memomize);
}
return this.fractal(factorialize);
});
यह एक और स्टैक सुझाव को कार्यान्वित करता है और मुझे फंक्शन को तथ्यात्मक (सत्य) (5) के रूप में कॉल करने की अनुमति देता है, जो कि मेरे लक्ष्यों में से एक था। : 3 मैंने कुछ अनावश्यक असाइनमेंट भी निकाले, और कुछ गैर-सार्वजनिक चर नामों को शॉर्टहैंड किया।
undefined
0 के लिए रिटर्न !. ES6 के isNumeric
साथ बदलने की अनुमति देता है Number.isInteger
। जैसी लाइनें factorials[0][factorials[1]]=factorials[0][factorial_index]*(factorials[1]+1);
पूरी तरह से अपठनीय हैं।
यहाँ एक नया जावास्क्रिप्ट फंक्शन फिल , मैप , कम और कंस्ट्रक्टर (और फैट एरो सिंटैक्स) का उपयोग किया जाता है:
Math.factorial = n => n === 0 ? 1 : Array(n).fill(null).map((e,i)=>i+1).reduce((p,c)=>p*c)
संपादित करें: n === 0 को संभालने के लिए अद्यतन किया गया
n === 0
? Math.factorial = n => Array.from({ length: n }).reduce((product, _, i) => product * (i + 1), 1)
function computeFactorialOfN(n) {
var output=1;
for(i=1; i<=n; i++){
output*=i;
} return output;
}
computeFactorialOfN(5);