2015-08-26 8 views
11

मुझे पता है कि यह अनाम कार्य नहीं है, लेकिन एक पहेली के रूप में मैंने अज्ञात कार्यों के माध्यम से एक पुनरावर्ती कार्य करने की कोशिश की। रिकर्सिव कार्यों का प्रोटोटाइप स्पष्ट रूप से फैक्टोरियल फ़ंक्शन है। समस्या यह है कि अज्ञात कार्यों के भीतर केस भेद बनाना मुश्किल है। क्या मैं अब तक क्या करने में कामयाब पीछा कर रहा है:रिकर्सिव बेनामी फ़ंक्शन Matlab

[email protected](cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;ans=cn;end'); 
[email protected](n)f(1,n,f); 

या वैकल्पिक रूप से:

[email protected](cn,n,f)eval('if n>1; f(cn*n,n-1,f);else;disp(cn);end'); 
[email protected](n)f(1,n,f); 

क्या बहुत संतोषजनक नहीं है कि आप अभी भी जब सीधे बताए इस सुविधा का उपयोग नहीं कर सकता है, a=f(3) अभी भी त्रुटि पैदा करता है, चूंकि को कोई मूल्य नहीं मिलता है।

तो मेरा सवाल यह है कि, क्या आप वास्तव में अनाम कार्यों के माध्यम से एक पुनरावर्ती कार्य कर सकते हैं उदा। फैक्टोरियल की गणना इस तरह से करता है जो उदा। a=f(3) केवल मूल matlab फ़ंक्शंस पर निर्भर है (या आप कमांड लाइन में बना सकते हैं, जैसा कि मैंने अपने उदाहरण में किया था)?

पीएस: मुझे पता है कि इसका कोई व्यावहारिक उपयोग नहीं है, यह एक चुनौती है कि आप मैटलैब के वाक्यविन्यास को कितना मोड़ और दुरुपयोग कर सकते हैं।

+0

क्या आपका मतलब अनाम कार्य है? फंक्शन हैंडल मेरे लिए ऑब्जेक्ट्स का एक विस्तृत वर्ग प्रतीत होता है। लेकिन मैं एक विशेषज्ञ नहीं हूं, इसलिए मैं वास्तव में पूछ रहा हूं। –

+0

@AndrasDeak निश्चित रूप से मैं करता हूं, इसे इंगित करने के लिए धन्यवाद! – flawr

+0

इस समय कोई Matlab एक्सेस नहीं है, लेकिन क्या आपने ऐसा कुछ करने की कोशिश की है, 'अगर n> 1; च (सीएन * n, n-1, च); अन्य; cn; end'? – patrik

उत्तर

5

हमें अब दो possibilites मिल गया, दोनों सेल arrays के उपयोग पर भरोसा करते हैं। ध्यान दें कि यह ऑक्टेव में काम नहीं कर सकता है।

कुंजी एक मामला भेदभाव का कार्यान्वयन था। पहले एक है कि मैं मिल गया है, पाया जा सकता है here.

इस विधि matlabs बूलियन मूल्यों, सत्य 1 के रूप में मूल्यांकन किया जा सकता है, जबकि झूठी 0 के रूप में मूल्यांकन किया जा सकता का उपयोग करता है।

if_ = @(pred_, cond_) cond_{ 2 - pred_ }(); 

यहाँ हम पहले तर्क के रूप में एक शर्त है, और दूसरा तर्क के रूप में एक 2 तत्व सेल सरणी प्रदान करने के लिए है। प्रत्येक सेल तत्व एक फ़ंक्शन हैंडल होना चाहिए जिसे कहा जाता है कि स्थिति सही है या सत्य नहीं है। हमारे भाज्य समारोह इस प्रकार दिखाई देगा:

fac = @(n,f)if_(n>1,{@()n*f(n-1,f),@()1}) 
[email protected](n)fac(n,fac); 
factorial_(10) 

@AndrasDeak जैसा कि नीचे टिप्पणी की: यहां महत्वपूर्ण बात यह है कि हम कार्यों और मूल्यों की नहीं की एक सेल सरणी है है। यह शॉर्ट सर्किटिंग प्रदान करता है, क्योंकि n*f(n-1,f) का मूल्यांकन नहीं किया जाता है जब तक कि हम संबंधित फ़ंक्शन @()n*f(n-1,f) पर कॉल न करें।

second method @beaker द्वारा पाया और कुछ हद तक अधिक लचीला है किया गया था:

iif = @(varargin) varargin{2*find([varargin{1:2:end}], 1, 'first')}(); 

इस तथ्य यह है कि आप गुमनाम कार्यों में भी varargin (तर्कों की चर राशि) का उपयोग कर सकते का उपयोग करता है। जब आप इस फ़ंक्शन को कॉल करते हैं तो आपको वैकल्पिक स्थितियां होती हैं और यदि स्थिति सत्य होती है तो उसे निष्पादित किया जाना चाहिए। यह भी switch निर्माण, या if ... else if ... else if ... (...) else ... निर्माण की अनुमति देता है। जब कॉल किया जाता है, तो यह पहली शर्त की तलाश करेगा जो सत्य है (find([varargin{1:2:end}], 1, 'first')) और संबंधित फ़ंक्शन को कॉल करें।भाज्य समारोह की हमारी उदाहरण इस प्रकार है:

fac = @(n,f)iif(n>1,@()n * f(n-1,f),true,@()1); 
[email protected](n)fac(n,fac); 
factorial_(10) 

संपादित करें: मज़ेदार तथ्य: क्या हम लाइन

[email protected](n)fac(n,fac); 

साथ क्या कर रहे भी Y-combinator आवेदन के रूप में जाना जाता है। असल में हम लिख सकते हैं कि

Y = @(f)@(x)f(x,f); 
factorial_=Y(f); 
+1

मैं दोनों मामलों में जोर देने का सुझाव देता हूं कि मूल्यांकन से तर्क की रक्षा के लिए '@()' की आवश्यकता है। चूंकि आप कॉल करते हैं, उदाहरण के लिए, 'मतलब (रैंड (3))', मैटलैब पहले 'रैंड (3)' का मूल्यांकन करता है, फिर उस मीट्रिक्स को 'माध्य' फ़ंक्शन में पास करता है। यदि आप '@()' भाग को छोड़ देंगे, तो 'iif' तत्कालीन अर्थहीन फ़ंक्शन का मूल्यांकन करने का प्रयास करेगा। मुख्य बिंदु: 'iif' फ़ंक्शन पहले 'सत्य' तर्क पर शॉर्ट-सर्किट में दिखाई देता है, लेकिन ऐसा नहीं होता है। –

संबंधित मुद्दे