एक पुनरावर्ती कार्य के रूप में 2 ** एन - 1 कैसे लिखें?


49

मुझे एक फंक्शन चाहिए जो n लेता है और 2 n - 1 देता है । यह काफी सरल लगता है, लेकिन फ़ंक्शन को पुनरावर्ती होना पड़ता है। अभी तक मेरे पास सिर्फ 2 n :

def required_steps(n):
    if n == 0:
        return 1
    return 2 * req_steps(n-1)

अभ्यास में कहा गया है: "आप मान सकते हैं कि पैरामीटर एन हमेशा एक सकारात्मक पूर्णांक है और 0 से अधिक है"


4
बस रिकॉर्ड के लिए, यह एक पारी और घटाव के साथ एक सामान्य व्यक्ति की तरह करना अधिक कुशल होना चाहिए। पाइथन पूर्णांकों की मनमानी चौड़ाई है इसलिए 1 << nयह अतिप्रवाह नहीं कर सकते हैं। यह (1<<n) - 1कई चरणों में विघटित करने के तरीके का आविष्कार करने के लिए एक अभ्यास प्रतीत होता है , शायद एक बार में प्रत्येक बिट सेट करना जैसे कुछ उत्तर दिखाते हैं।
पीटर कॉर्ड्स

8
def fn(n): if n == 0: return 1; return (2 << n) - fn(0); # technically recursive
मॉसबॉयस

3
@Voo: कार्ल नहीं, लेकिन कृपया मुझे वह सब कुछ बताएं जो इसमें निहित हैC:\MyFolder
Flater

1
@Voo: निर्भरता या नहीं एक अभ्यास के लिए अप्रासंगिक है जो विशुद्ध रूप से पुनरावृत्ति की अवधारणा को पढ़ाने पर केंद्रित है। मैं कक्षाओं / विधियों का एक बुनियादी नकली सेट बना सकता था जिसका छात्र उपयोग कर सकते थे। आप किसी ऐसी चीज़ पर ध्यान केंद्रित कर रहे हैं जो पूरी तरह से व्यायाम के बिंदु के अलावा है। फ़ाइल सिस्टम नेविगेशन का उपयोग करना एक अच्छा उदाहरण है क्योंकि छात्र आमतौर पर फ़ोल्डर और फ़ाइलों की अंतर्निहित आवर्तक प्रकृति को समझते हैं (अर्थात फ़ोल्डर्स को एक दूसरे में अनिश्चित काल तक
घोंसला बनाया

1
@Voo नहीं मैं कह रहा हूं कि आप एक पुनरावर्ती डेटा संरचना दिखा कर पुनरावृत्ति सिखा सकते हैं। मुझे इस बात का कोई अंदाजा नहीं है कि आप इसे क्यों समझते हैं।
Flater

जवाबों:


54

2**n -1भी है 1 + 2 + 4 + ... + 2 n-1 जो (2 की शक्ति से 1 घटाना दूसरा एक के बिना) एक भी पुनरावर्ती क्रिया में बनाया जा सकता है।

संकेत : 1 + 2 * (1 + 2 * (...))

नीचे दिए गए समाधान, यह न देखें कि क्या आप पहले संकेत का प्रयास करना चाहते हैं।


यह कार्य nशून्य से अधिक होने की गारंटी देता है (जैसा कि समस्या कथन में वास्तव में वादा किया गया था):

def required_steps(n):
    if n == 1: # changed because we need one less going down
        return 1
    return 1 + 2 * required_steps(n-1)

एक अधिक मजबूत संस्करण शून्य और नकारात्मक मान भी संभालेगा:

def required_steps(n):
    if n < 0:
        raise ValueError("n must be non-negative")
    if n == 0:
        return 0
    return 1 + 2 * required_steps(n-1)

(गैर-पूर्णांक के लिए एक चेक जोड़ना अभ्यास के रूप में छोड़ दिया गया है।)


4
लेकिन required_steps(0)अब अनंत पुनरावृत्ति का कारण बनता है
धन्यवाद

7
2^0 - 1== 0. ifउस मामले के लिए एक और जोड़ें ।
h4z3

9
@ user633183 हां, मुझे पता है कि कुल कार्य क्या है। क्या आप? क्योंकि यह कभी भी कुल कार्य नहीं होगा। और न ही अन्य उत्तर कुल कार्य हैं। और हां, उन्हें कुल कार्य करने के लिए अधिक कोड की आवश्यकता होगी। - जैसा कि मैंने कहा, हमारे पास कोई डोमेन नहीं है। हमें यह मान लेना चाहिए कि हमारा डोमेन क्या है? यहां तक ​​कि अगर यह सिर्फ है int, हम नहीं जानते कि क्या करना है जब n <0। गणना? एक त्रुटि फेंको? वापसी 0? इस मामले में, हम केवल एक आंशिक कार्य कर सकते हैं (इसे उन चीजों के लिए परिभाषित करें जिन्हें हम जानते हैं कि परिणाम क्या है)।
h4z3

4
ओपी के कोड में आधार मामला है 0और n - 1उपप्रोमी के लिए उपयोग करता है । नेचुरल नंबर्स का एक डोमेन एक अच्छा फिट लगता है।
धन्यवाद

4
आपको बहुत - बहुत धन्यवाद! मेरी विनम्र राय में, यह मेरी विशिष्ट समस्या का सबसे अच्छा समाधान है। मैं n के लिए संभावित मूल्यों को राज्य नहीं करता था, वास्तव में क्षमा करें! मुझे पता है कि यह थोड़े महत्वपूर्ण है ... व्यायाम में कहा गया है: "आप मान सकते हैं कि पैरामीटर एन हमेशा एक सकारात्मक पूर्णांक और 0 से अधिक है"
काजिस

37

एक पुनरावर्ती दृष्टिकोण के साथ एक समस्या को हल करने के लिए आपको यह पता लगाना होगा कि आप किसी दिए गए इनपुट के साथ फ़ंक्शन को एक अलग इनपुट के साथ फ़ंक्शन के रूप में कैसे परिभाषित कर सकते हैं। इस मामले में f(n) = 2 * f(n - 1) + 1, आप कब से कर सकते हैं:

def required_steps(n):
    return n and 2 * required_steps(n - 1) + 1

ताकि:

for i in range(5):
    print(required_steps(i))

आउटपुट:

0
1
3
7
15

9

आप किसी अन्य फ़ंक्शन के लिए वास्तव में पुनरावर्ती भाग निकाल सकते हैं

def f(n):
    return required_steps(n) - 1

या आप एक ध्वज सेट कर सकते हैं और परिभाषित कर सकते हैं कि कब घटाना है

def required_steps(n, sub=True):
    if n == 0: return 1
    return 2 * required_steps(n-1, False) - sub

>>> print(required_steps(10))
1023

0

परिणाम के लिए एक अतिरिक्त पैरामीटर का उपयोग करना, r-

def required_steps (n = 0, r = 1):
  if n == 0:
    return r - 1
  else:
    return required_steps(n - 1, r * 2)

for x in range(6):
  print(f"f({x}) = {required_steps(x)}")

# f(0) = 0
# f(1) = 1
# f(2) = 3
# f(3) = 7
# f(4) = 15
# f(5) = 31

आप इसे बिटवाइस लेफ्ट शिफ्ट का उपयोग करके भी लिख सकते हैं, <<-

def required_steps (n = 0, r = 1):
  if n == 0:
    return r - 1
  else:
    return required_steps(n - 1, r << 1)

आउटपुट एक ही है


2
एक सरल गुणन अभ्यास के लिए बिटवाइज़ ऑपरेशन को शामिल करने के लिए अनावश्यक .. बिल्कुल भी पठनीय नहीं। इसके अलावा, किसी elseभी फ़ंक्शन में क्लॉज़ की कोई आवश्यकता नहीं है
राफेलक

केवल अंतर बदल रहा r * 2है r << 1और यह "बिल्कुल पठनीय नहीं है"? 😂
धन्यवाद

2
एक 2 पैरामीटर का आविष्कार करना बस इसे एक लूप में बदल देता है जो बायीं तरफ शिफ्ट होता nहै और फिर घटता है। 1. लगता है कि कम सुरुचिपूर्ण भी आवश्यक है, हालांकि पूरी बात अक्षमता बनाम एक अभ्यास है (1<<n) - 1
पीटर कॉर्ड्स

1
@PeterCordes: राज्य को एक संचायक पैरामीटर में ले जाना एक पुनरावर्ती कॉल को पुनरावर्ती कॉल में बदलने का मानक तरीका है। अब, दुर्भाग्य से, पायथन उचित टेल कॉल का समर्थन नहीं करता है, यहां तक ​​कि उचित टेल रिकर्सियन भी नहीं है, लेकिन इसका मतलब यह नहीं है कि यह सीखने के लिए एक उपयोगी तकनीक नहीं है ताकि आप इसे अन्य भाषाओं में लागू कर सकें जो उचित टेल कॉल को लागू करते हैं। या कम से कम उचित पूंछ पुनरावृत्ति।
जोर्ग डब्ल्यू मित्तग

1
@ JörgWMittag हां, लेकिन इस मामले में इस तथ्य को उजागर करना मुश्किल है कि यह लूप के रूप में अधिक स्वाभाविक होगा । शायद यह सिर्फ इतना है कि मैं विधानसभा भाषा और प्रदर्शन पर इतना समय बिताता हूं, लेकिन पूंछ-पुनरावृत्ति का उपयोग करके "लूप" लिखना एक अनिवार्य भाषा में व्यर्थ लगता है जब आप सिर्फ एक लूप लिख सकते थे। या शायद जो मुझे इस उत्तर के बारे में परेशान करता है वह सिर्फ यह है कि कैसे विघटित होना है: एक-एक-समय में बदलाव और फिर अंतिम रूप से बेसकेज़ के रूप में घटाना। शायद दोनों का मेल।
पीटर कॉर्ड्स

0

N के मूल मान को याद रखने के लिए एक प्लेसहोल्डर रखें और फिर पहले चरण के लिए यानी n == Nवापस लौटें2^n-1

n = 10
# constant to hold initial value of n
N = n
def required_steps(n, N):
    if n == 0:
        return 1
    elif n == N:
        return 2 * required_steps(n-1, N) - 1
    return 2 * required_steps(n-1, N)

required_steps(n, N)

-1

"-1" की ऑफसेट प्राप्त करने का एक तरीका यह है कि इसे पहले फ़ंक्शन कॉल से डिफ़ॉल्ट मान के साथ एक तर्क का उपयोग करके रिटर्न में लागू किया जाए, फिर पुनरावर्ती कॉल के दौरान ऑफसेट तर्क को शून्य पर सेट करें।

def required_steps(n, offset = -1):
    if n == 0:
        return 1
    return offset + 2 * required_steps(n-1,0)

-1

पहले दिए गए सभी भयानक उत्तरों के शीर्ष पर, नीचे आंतरिक कार्यों के साथ इसका कार्यान्वयन दिखाई देगा।

def outer(n):
    k=n
    def p(n):
        if n==1:
            return 2
        if n==k:
            return 2*p(n-1)-1
        return 2*p(n-1)
    return p(n)

n=5
print(outer(n))

मूल रूप से, यह n की k को वैश्विक मान दे रहा है और उचित तुलना के साथ इसके माध्यम से पुनरावृत्ति कर रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.