मैं स्कैला के लिए बहुत नया हूं, इसलिए मेरी अज्ञानता को क्षमा करें! मैं पूर्णांक से जुड़े पूर्णांक के जोड़े की पुनरावृत्ति करने की कोशिश कर रहा हूं। उदाहरण के लिए, यदि अधिकतम 5 है, तो यात्रा लौटना चाहिए:पूर्णांक (स्कैला) के जोड़े की पूंछ-पुनरावर्ती बाध्य धारा?
(0, 0), (0, 1), ..., (0, 5), (1, 0), ..., (5, 5)
मैं कोशिश करने के लिए चुन लिया है और पूंछ पुनरावर्ती एक स्ट्रीम के रूप में इस वापसी:
@tailrec
def _pairs(i: Int, j: Int, maximum: Int): Stream[(Int, Int)] = {
if (i == maximum && j == maximum) Stream.empty
else if (j == maximum) (i, j) #:: _pairs(i + 1, 0, maximum)
else (i, j) #:: _pairs(i, j + 1, maximum)
}
tailrec एनोटेशन के बिना कोड काम करता है:
scala> _pairs(0, 0, 5).take(11)
res16: scala.collection.immutable.Stream[(Int, Int)] = Stream((0,0), ?)
scala> _pairs(0, 0, 5).take(11).toList
res17: List[(Int, Int)] = List((0,0), (0,1), (0,2), (0,3), (0,4), (0,5), (1,0), (1,1), (1,2), (1,3), (1,4))
लेकिन यह मेरे लिए पर्याप्त नहीं है। संकलक सही ढंग से उनका कहना है कि _pairs की अंतिम पंक्ति _pairs नहीं लौटा रहा है:
could not optimize @tailrec annotated method _pairs: it contains a recursive call not in tail position
else (i, j) #:: _pairs(i, j + 1, maximum)
^
तो, मैं कई प्रश्न हैं:
- सीधे ऊपर कार्यान्वयन को संबोधित कर, कैसे करता है एक पूंछ पुनरावर्ती वापसी स्ट्रीम [(Int, Int)]?
- एक कदम पीछे लेना, पूर्णांक के बाध्य अनुक्रमों को फिर से चलाने के लिए सबसे मेमोरी-कुशल तरीका क्या है? मैं रेंज पर पुनरावृत्ति नहीं करना चाहता क्योंकि Range extends IndexedSeq, और मैं नहीं चाहता कि अनुक्रम पूरी तरह स्मृति में मौजूद हो। या मैं गलत हूँ? अगर मैं रेंज पर पुन: प्रयास करता हूं। क्या मैं इसे स्मृति में आने से बचता हूं? (!)
अजगर, सभी मैं चाहता हूँ है:
In [6]: def _pairs(maximum):
...: for i in xrange(maximum+1):
...: for j in xrange(maximum+1):
...: yield (i, j)
...:
In [7]: p = _pairs(5)
In [8]: [p.next() for i in xrange(11)]
Out[8]:
[(0, 0),
(0, 1),
(0, 2),
(0, 3),
(0, 4),
(0, 5),
(1, 0),
(1, 1),
(1, 2),
(1, 3),
(1, 4)]
आपकी मदद के लिए धन्यवाद! अगर आपको लगता है कि मुझे संदर्भ/एपीआई दस्तावेज़/कुछ और पढ़ने की जरूरत है तो कृपया मुझे बताएं, क्योंकि मैं सीखना चाहता हूं।
अपने जवाब के लिए धन्यवाद! मैं समझता हूं कि मैंने जो किया वह पूंछ रिकर्सिव नहीं है, और मैं निश्चित रूप से 'for' का उपयोग करना पसंद करूंगा। मेरी समस्या यह है कि जैसा कि आपने सुझाव दिया है, 'जोड़े', 'इंडेक्सेडस्क' लौटाता है। इसलिए जब 'जोड़े' कहा जाता है तो पूरा परिणाम स्मृति में मौजूद होगा। क्या आप इस बात से बचने के लिए विचारों का उपयोग कैसे कर सकते हैं? –
और क्या आपके पास स्ट्रीम और थंक्स के बारे में अधिक जानकारी और संदर्भ हैं? मैं इस बारे में बहुत उत्सुक हूं कि मैं गैर-पूंछ-कॉल अनुकूलित फ़ंक्शन को दोबारा कॉल करके स्टैक को उड़ाने वाला नहीं हूं जहां मैं कोरआउट का उपयोग नहीं करता हूं। सीखने के लिए बहुत कुछ! –
@AsimIhsan: मैं इन सवालों के जवाब में जवाब दूंगा। अच्छे जवाब के लिए –