পাইথন: জেনারেটর হিসাবে পুনরাবৃত্ত আলগোরিদিম ব্যবহার করে


99

সাম্প্রতিককালে আমি অযৌক্তিক প্রতিবন্ধকতা সহ কিছু সিক্যুয়েন্স তৈরি করতে একটি ফাংশন লিখেছিলাম। সমস্যাটি প্রাকৃতিক পুনরাবৃত্তির সমাধান নিয়ে আসে। এখন এটি ঘটেছিল, এমনকি অপেক্ষাকৃত ছোট ইনপুটগুলির জন্যও, সিকোয়েন্সগুলি কয়েক হাজার thus

এখানে একটি উদাহরণ। মনে করুন আমরা একটি পুনরাবৃত্ত ফাংশন সহ স্ট্রিংয়ের সমস্ত ক্রিয়াকলাপ গণনা করতে চাই। নিম্নলিখিত নিষ্পাপ আলগোরিদম একটি অতিরিক্ত আর্গুমেন্ট 'স্টোরেজ' নেয় এবং যখনই এটি খুঁজে পায় এটিতে একটি অনুমতি যুক্ত করে:

def getPermutations(string, storage, prefix=""):
   if len(string) == 1:
      storage.append(prefix + string)   # <-----
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], storage, prefix+string[i])

storage = []
getPermutations("abcd", storage)
for permutation in storage: print permutation

(দয়া করে অদক্ষতার বিষয়ে চিন্তা করবেন না এটি কেবল উদাহরণ example)

এখন আমি আমার ফাংশনটিকে একটি জেনারেটরে রূপান্তর করতে চাই, অর্থাৎ এটি স্টোরেজ তালিকায় যুক্ত করার পরিবর্তে কোনও ক্রমশক্তি অর্জন করতে:

def getPermutations(string, prefix=""):
   if len(string) == 1:
      yield prefix + string             # <-----
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], prefix+string[i])

for permutation in getPermutations("abcd"):
   print permutation

এই কোডটি কাজ করে না (ফাংশনটি খালি জেনারেটরের মতো আচরণ করে)।

আমি কিছু অনুপস্থিত করছি? উপরের পুনরাবৃত্তির অ্যালগরিদমকে পুনরায় না করে কোনও জেনারেটরে পরিবর্তন করার কোনও উপায় আছে কি ?

উত্তর:


117
def getPermutations(string, prefix=""):
    if len(string) == 1:
        yield prefix + string
    else:
        for i in xrange(len(string)):
            for perm in getPermutations(string[:i] + string[i+1:], prefix+string[i]):
                yield perm

বা সঞ্চালক ছাড়াই:

def getPermutations(string):
    if len(string) == 1:
        yield string
    else:
        for i in xrange(len(string)):
            for perm in getPermutations(string[:i] + string[i+1:]):
                yield string[i] + perm

29
পাইথন ৩.৪-এ, আপনি শেষ দুটি লাইন প্রতিস্থাপন করতে পারেন yield from getPermutations(string[:i] + string[i+1:]), যা বিভিন্ন উপায়ে আরও দক্ষ!
ম্যানুয়েল ইবার্ট

4
আপনার এখনও কোনওভাবে ফলাফল তৈরি করতে হবে। ব্যবহার yield fromপ্রয়োজন হবে সঁচায়ক যুক্তি ব্যবহার করবেন ( prefix)।
মার্কাস জারদারোট

পরামর্শ: আরও একটি জেনারেটর সংজ্ঞায়িত করুন যা string[i],string[:i]+string[i+1:]জোড়া ফেরত দেয় । তারপরে এটি হবে:for letter,rest in first_letter_options(string): for perm in getPermuations(rest): yield letter+perm
টমাস অ্যান্ড্রুজ

29

এটি- len(string)ডিডিপি পুনরাবৃত্তি এড়ায়, এবং সাধারণভাবে জেনারেটর-অভ্যন্তরীণ জেনারেটরগুলি পরিচালনা করার একটি দুর্দান্ত উপায়:

from types import GeneratorType

def flatten(*stack):
    stack = list(stack)
    while stack:
        try: x = stack[0].next()
        except StopIteration:
            stack.pop(0)
            continue
        if isinstance(x, GeneratorType): stack.insert(0, x)
        else: yield x

def _getPermutations(string, prefix=""):
    if len(string) == 1: yield prefix + string
    else: yield (_getPermutations(string[:i]+string[i+1:], prefix+string[i])
            for i in range(len(string)))

def getPermutations(string): return flatten(_getPermutations(string))

for permutation in getPermutations("abcd"): print permutation

flattenআমাদের কেবল আরেকটি জেনারেটরে অগ্রগতি চালিয়ে যাওয়ার অনুমতি দেয় কেবল yieldএটির মাধ্যমে, এটির মাধ্যমে পুনরাবৃত্তি না করে এবং yieldপ্রতিটি আইটেম নিজেই ইঙ্গিত করে ing


পাইথন ৩.৩ yield fromসিন্টেক্সে যুক্ত করবে , যা উপ-জেনারেটরে প্রাকৃতিক প্রতিনিধিদের অনুমতি দেয়:

def getPermutations(string, prefix=""):
    if len(string) == 1:
        yield prefix + string
    else:
        for i in range(len(string)):
            yield from getPermutations(string[:i]+string[i+1:], prefix+string[i])

20

প্রম্পটেশন পেতে অভ্যন্তর কল - এটি একটি জেনারেটরও।

def getPermutations(string, prefix=""):
   if len(string) == 1:
      yield prefix + string            
   else:
      for i in range(len(string)):
         getPermutations(string[:i]+string[i+1:], prefix+string[i])  # <-----

আপনাকে লুপের মাধ্যমে পুনরাবৃত্তি করতে হবে (@ মিশরএক্সএক্স পোস্টিং দেখুন, যা আমাকে কয়েক সেকেন্ডের মধ্যে সরিয়ে নিয়েছে!)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.