1 मैं एक सीमित-कम फैक्टोरियल फ़ंक्शन (जिज्ञासा से बाहर) बनाने की कोशिश कर रहा हूं। यह n
(100000 तक की कोशिश की गई और यह काम करने लगता है, हालांकि मैं काम नहीं कर सकता) शुद्धता के लिए उत्पादन मूल्य की जाँच करें, क्योंकि अच्छी तरह से, यह बड़े है!)स्टैक ओवरफ्लोइंग
(BigInt(1) to n).reduceRight(_*_)
लेकिन मुझे डर है कि पूरे BigInt(1) to n
रेंज स्मृति में हो सकता है कर रहा हूँ, जबकि मैं सिर्फ यह तत्व तत्व द्वारा reduceRight
के लिए की जरूरत है। स्काला के मानक पुस्तकालय कोड पर एक नज़र यह लग रहा है BigInt(1) to n
वास्तव में पूरी Range
और नहीं एक आलसी Stream
आउटपुट लेकिन मैं Stream.range
जो मैं इस तरह उपयोग कर सकते हैं पाया की तरह ले रहा है (नोटिस n+1
, धारा रेंज अनन्य है)
Stream.range[BigInt](BigInt(1), BigInt(n+1)).reduceRight(_*_)
यह लेकिन n=100000
के लिए मैं इस ढेर अतिप्रवाह मिल (किसी कारण इसे थोड़ा समय लेता है! जो मुझे लगता है कि शायद सामान्य श्रेणी के वास्तव में एक Stream
भी है? बनाता है के लिए) के लिए काम करता n=10000
java.lang.StackOverflowError
at java.math.BigInteger.add(Unknown Source)
at scala.math.BigInt.$plus(BigInt.scala:161)
at scala.math.Numeric$BigIntIsIntegral$class.plus(Numeric.scala:28)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$BigIntIsIntegral$.plus(Numeric.scala:40)
at scala.math.Numeric$Ops.$plus(Numeric.scala:208)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$$anonfun$range$1.apply(Stream.scala:695)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:634)
at scala.collection.immutable.Stream$Cons.tail(Stream.scala:626)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:130)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
at scala.collection.LinearSeqOptimized$class.reduceRight(LinearSeqOptimized.scala:131)
at scala.collection.immutable.Stream.reduceRight(Stream.scala:47)
...
ऐसा नहीं है कि reduceRight
ही इस
reduceRight(reduceRight(first, second, op), third, op)...
और इस तरह ढेर अतिप्रवाह तरह बुला रहा है स्पष्ट है। मुझे लगता है कि यह पूंछ-कॉल अनुकूलित नहीं है क्योंकि यह पहले मूल्य को वापस करने से पहले कम करता है और फिर संचालित होता है, इसलिए इसे अनुकूलित नहीं किया जा सकता है। तब मैं इस समस्या से कैसे संपर्क कर सकता हूं? क्या मुझे कार्यात्मक दृष्टिकोण को कम करना चाहिए और कम करने के लिए कस्टम अनिवार्य-शैली कोड का लक्ष्य रखना चाहिए?
मुझे एक बहुत ही अजीब चीज़ के रूप में क्या रोकता है यह है कि (BigInt(1) to n).reduceRight(_*_)
बड़े n
के लिए ओवरफ़्लो नहीं होता है जबकि लगभग एक ही स्ट्रीम का उपयोग करता है ... यहां क्या हो रहा है?
अन्य उत्तर में मेरी टिप्पणी देखें (यहां भी लागू होता है।) इसके अलावा: मैं टीसीआर का उपयोग करके सामान्य फैक्टोरियल कार्यान्वयन से बचना चाहता हूं क्योंकि यह आलसी श्रेणियों का उपयोग करने के लिए एक अभ्यास के रूप में है। – kaoD
@kaoD - इसे सीमा की आवश्यकता नहीं है और अंतिम तत्व से शुरू नहीं होता है। उदाहरण देखें (आरईपीएल में पेस्ट करें)। –