برنامه یافتن بلندترین زیر رشته جناس قلب – به زبان ساده

۵۲۰
۱۴۰۲/۰۴/۲۰
۱۲ دقیقه
PDF
آموزش متنی جامع
امکان دانلود نسخه PDF

در این مطلب، روش پیدا کردن بلندترین زیر رشته جناس قلب (Longest Palindromic Subsequence) بیان و پیاده‌سازی روش ارائه شده، با استفاده از زبان‌های برنامه‌نویسی گوناگون شامل «سی‌پلاس‌پلاس» (++C)، «سی» (C)، «جاوا» (Java)، «پایتون ۳» (Python 3) و «پی‌اچ‌پی» (PHP) انجام شده است. در اینجا، یک دنباله داده شده است. هدف، پیدا کردن طول بلندترین زیر رشته جناس قلب برای آن است.

برنامه یافتن بلندترین زیر رشته جناس قلب – به زبان سادهبرنامه یافتن بلندترین زیر رشته جناس قلب – به زبان ساده
فهرست مطالب این نوشته
997696

بلندترین زیر رشته جناس قلب -- به زبان ساده

به عنوان مثالی دیگر، اگر دنباله داده شده «BBABCBCAB» است، خروجی باید ۷ باشد، زیرا «BABCBAB» بلندترین زیر رشته دارای جناس قلب در این متن است. «BBBBB» و «BBCBB» نیز زیر رشته‌های دارای جناس قلب از دنباله داده شده به عنوان ورودی، هستند؛ اما بلندترین آن‌ها محسوب نمی‌شوند. راهکار ساده برای این مساله، تولید همه زیر دنباله‌ها از یک دنباله داده شده و پیدا کردن بلندترین زیر رشته جناس قلب است. این راهکار دارای پیچیدگی زمانی نمایی است.

ویژگی‌های برنامه‌نویسی پویا در مساله محاسبه بلندترین زیر رشته جناس قلب

در ادامه، بررسی می‌شود که این مساله چگونه هم دارای خصوصیات مهم «برنامه‌نویسی پویا» (Dynamic Programming | DP) است و هم می‌تواند به طور موثری با برنامه‌نویسی پویا حل شود.

  • ساختار بهینه

فرض می‌شود X[0..n-1]‎ دنباله ورودی به طول n و L(0, n-1)‎ طول بلندترین زیر دنباله دارای جناس قلب X[0..n-1]‎ است. اگر اولین و آخرین کاراکترهای X مشابه باشند، داریم: L(0, n-1) = L(1, n-2) + 2؛ در غیر این صورت، L(0, n-1) = MAX (L(1, n-1), L(0, n-2))‎. در ادامه، یک راهکار بازگشتی متداول برای حل این مساله، ارائه شده است.

// Every single character is a palindrome of length 1
L(i, i) = 1 for all indexes i in given sequence

// IF first and last characters are not same
If (X[i] != X[j])  L(i, j) =  max{L(i + 1, j),L(i, j - 1)} 

// If there are only 2 characters and both are same
Else if (j == i + 1) L(i, j) = 2  

// If there are more than two characters, and first and last 
// characters are same
Else L(i, j) =  L(i + 1, j - 1) + 2

در ادامه، الگوریتم بالا به صورت خط به خط تشریح شده است.

// Every single character is a palindrome of length 1
L(i, i) = 1 for all indexes i in given sequence

هر کاراکتر یکتا، جناس قلبی به طول یک است. برای همه اندیس‌های i در یک دنباله داده شده، L(i, i) = 1 است.

// IF first and last characters are not same
If (X[i] != X[j]) L(i, j) = max{L(i + 1, j),L(i, j - 1)}

اگر اولین و آخرین کاراکتر مشابه نباشند، رابطه بالا برقرار است.

// If there are only 2 characters and both are same
Else if (j == i + 1) L(i, j) = 2

اگر تنها دو کاراکتر وجود داشته و هر دو نیز مشابه باشند، رابطه بالا برقرار است.

// If there are more than two characters, and first and last 
// characters are same
Else L(i, j) = L(i + 1, j - 1) + 2

اگر بیش از دو کاراکتر وجود داشته باشند و اولین و آخرین کاراکتر مشابه باشند، رابطه بالا برقرار است.

  • زیرمسائل هم‌پوشان

روش بازگشتی یافتن بلندترین زیر رشته جناس قلب

در ادامه، یک پیاده‌سازی کوتاه و بازگشتی از مساله LPS ارائه شده است. پیاده‌سازی این روش، به سادگی و با ساختار بازگشتی بیان شده در بالا، امکان‌پذیر است.

برنامه یافتن بلندترین زیر رشته جناس قلب در ++C به روش بازگشتی

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در C به روش بازگشتی

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در جاوا به روش بازگشتی

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در پایتون ۳ به روش بازگشتی

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در سی شارپ به روش بازگشتی

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در PHP به روش بازگشتی

خروجی قطعه کدهای بالا به صورت زیر است.

The length of the LPS is 5

با در نظر داشتن پیاده‌سازی بالا، در ادامه «درخت بازگشتی جزئی» (Partial Recursion Tree) به طول ۶ با همه کاراکترهای متفاوت آن ارائه شده است.

L(0, 5)
             /        \ 
            /          \  
        L(1,5)          L(0,4)
       /    \            /    \
      /      \          /      \
  L(2,5)    L(1,4)  L(1,4)  L(0,3)

پیدا کردن بلندترین زیر رشته جناس قلب با برنامه‌نویسی پویا

در درخت بازگشتی جزئی که در بخش پیشین ارائه شد، L(1, 4)‎ دو بار حل می‌شود. اگر یک درخت بازگشتی کامل ترسیم شود، می‌توان مشاهده کرد که زیرمسائل بسیاری وجود دارند که دوباره و دوباره حل می‌شوند. از آنجا که مسائل مشابه چند بار فراخوانی می‌شوند، این مساله دارای خصوصیت زیرمسائل هم‌پوشان است.

بنابراین، مساله LPS هر دو خصوصیت مسائل برنامه‌نویسی پویا را دارد. مانند دیگر مسائل مرسوم برنامه‌نویسی پویا، محاسبه مجدد زیر مسائل مشابه با ساخت یک آرایه موقتی L[][]‎ به صورت پایین به بالا قابل انجام است.

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در ++C به روش برنامه‌نویسی پویا

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در جاوا به روش برنامه‌نویسی پویا

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در پایتون به روش برنامه‌نویسی پویا

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در #C به روش برنامه‌نویسی پویا

برنامه پیدا کردن بلندترین زیر رشته جناس قلب در PHP به روش برنامه‌نویسی پویا

خروجی قطعه کدهای بالا به صورت زیر است.

The lnegth of the LPS is 7

پیچیدگی زمانی پیاده‌سازی بالا از درجه O(n2)‎ است. این میزان، از پیچیدگی زمانی بدترین حالت پیاده‌سازی بازگشتی ساده نیز بهتر است.

اگر نوشته بالا برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

^^

بر اساس رای ۴ نفر
آیا این مطلب برای شما مفید بود؟
اگر پرسشی درباره این مطلب دارید، آن را با ما مطرح کنید.
منابع:
GeeksforGeeks
PDF
مطالب مرتبط
۱ دیدگاه برای «برنامه یافتن بلندترین زیر رشته جناس قلب – به زبان ساده»

salam . mamnun az etelaatetun . mikhastam bedunam chetor mishe hamzaman ba be dast avordan e toole LPS , khod e un ro ham be dast ovord ? yani alave bar tulesh , khod e subsequence ro ham dar biarim.

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *