برنامه نویسی

نحوه انجام جستجوی باینری برای آرایه Ruby توسط #bsearch

ما گاهی اوقات باید بررسی کنیم که آیا یک مقدار در یک آرایه گنجانده شده است یا خیر. روشهای زیادی برای دستیابی به آن وجود دارد ، به عنوان مثال Array#include?با Array#find، و غیره اما آنها از جستجوی خطی استفاده می کنند ، که پیچیدگی زمان است O(n)بشر اگر آن باشد آرایه مرتب شده، ما می دانیم جستجوی دودویی می تواند به شما بدهد O(logn) سرعت این شرم آور خواهد بود اگر نمی دانستید که آرایه روبی می تواند جستجوی باینری را از طریق جعبه انجام دهد Array#bsearchبشر متأسفانه ، ممکن است استفاده از بسیاری از افراد برای استفاده از آن ، شهودی نباشد. بیایید ابتدا چند نمونه را ببینیم:

نمونه هایی از آرایه#bsearch

اگر نمی دانید چه اتفاقی در آنجا افتاده است ، می توانید به خواندن این مقاله ادامه دهید تا بدانید که

دو چیز بسیار مهم وجود دارد که باید هنگام استفاده از آن بدانید Array#bsearchبشر اول ، فقط می توان آن را در یک انجام داد آرایه مرتب شدهبشر Array#bsearch آرایه را برای شما مرتب نمی کند (می توانید تماس بگیرید array.sort اول اگر مطمئن نیستید). دوم ، Array#bsearch داشتن دو حالتبشر این بدان معناست که دو روش مختلف برای استفاده از آن دارد. حالت اول نامیده می شود حالت-minimum را پیدا کنید، و دیگری نامیده می شود حالت پیدا کردنبشر این دو حالت در واقع یک کار بسیار مشابه انجام می دهند ، اما شما باید دو بلوک کاملاً متفاوت را برای آن ارسال کنید.

حالت-minimum را پیدا کنید

هنگام استفاده از حالت Find-Minimum ،

  1. بلوکی که به #bsearch باید برگردد Boolean ارزش ، false یا trueبشر
  2. اگر درخواست کنیم Array.map با همان بلوک ، باید یک سری از false مقادیر به دنبال یک سری از true مقادیر
  3. #bsearch اولین عنصر بازگشت را برمی گرداند true

من معتقدم که هنگام دیدن نمونه های واقعی ، درک آن آسان تر است.

array = [1, 3, 5, 7, 9]
array.bsearch { |x| x >= 5 } # => 5
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برمی گردد 5، چون 5 اولین عنصری است که باعث ایجاد بلوک می شود { |x| x >= 5 } بازگشت true:

# compute x >= 5 for all elements
# [1,     3,     5,    7,    9 ]
[false, false, true, true, true]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اگر از دیگری به بلوک دیگری استفاده کنیم { |x| x >= 6 }

array.bsearch { |x| x >= 6 } # => 7
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برمی گردد 7بشر چرا؟ باز هم ، به این دلیل است که 7 آیا اولین عنصر بازگشت بلوک است true


# [1,     3,     5,     7,    9 ]
[false, false, false, true, true]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اگر از بلوک استفاده کنم { |x| x >= 10 }با

array.bsearch { |x| x >= 10 } # => nil
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

زیرا هیچ عنصری در آرایه وجود ندارد که بتواند بلوک را بازگرداند true، nil بازگردانده خواهد شد

حالت پیدا کردن

هنگام استفاده از حالت Find-Any ،

  1. بلوکی که به #bsearch باید برگردد Numeric ارزش
  2. بازگشت شماره مثبت اگر یک عنصر آرایه باشد کوچکتر از مقادیری که در حال جستجو هستید
  3. بازگشت عدد منفی اگر یک عنصر آرایه باشد بیشتر از مقادیری که در حال جستجو هستید
  4. باید برگردد صفر، اگر عنصر با آنچه در حال جستجو است مطابقت دارد

حتی اگر قوانین فوق بسیار پیچیده تر از آن باشد حالت-minimum را پیدا کنید، به من اعتماد کن ، این نیز ساده است.

array = [1, 3, 5, 7, 9]
array.bsearch { |x| 5 <=> x } # => 5
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

چیست <=>؟ این <=> نامیده می شود مقایسه 3 طرفه، با نام مستعار اپراتور سفینه فضاییبشر اگر مقایسه کنیم a <=> b

  • اگر a < b، سپس نتیجه است -1
  • اگر a == b، سپس نتیجه است 0
  • اگر a > b، سپس نتیجه است 1

اگر واقعاً می خواهید آن را به خاطر بسپارید ، امیدوارم که تصویر زیر بتواند به شما کمک کند:
https%3A%2F%2Fdev to uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh80ejif5ikfricqy8ll6” loading=”lazy” width=”800″ height=”523″/>

به هر حال ، با بازگشت به مثال ما ، بیایید نتایج محاسبه شده را ببینیم { |x| 5 <=> x } برای هر عنصر:

array.map { |x| 5 <=> x }
# [1, 1, 0, -1, -1]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

5 بازگشت بلوک 0، بنابراین 5 برگردانده شده است اگر سعی می کنم جستجو کنم 6

array.bsearch { |x| 6 <=> x } # => nil
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

این صفر را برمی گرداند زیرا نتایج محاسبه شده از { |x| 6 <=> x } است ،

array.map { |x| 6 <=> x }
# [1, 1, 1, -1, -1]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

و ندارد 0 در آن

حالت Find-Any بسیار قدرتمند است. ما می توانیم به جای یک عنصر واحد ، یک دامنه را جستجو کنیم. به عنوان مثال ،

array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
array.bsearch do |x|
  if x < 4
    1
  elsif x > 6
    -1
  else
    0
  end
end
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

زیرا نتایج بلوک آرایه:

# [1, 2, 3, 4, 5, 6,  7,  8,  9, 10]
  [1, 1, 1, 0, 0, 0, -1, -1, -1, -1]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

4با 5 وت 6 بازگشت بلوک 0، بنابراین array.bsearch باز خواهد گشت هیچ در نتیجه یکی از آنها به همین دلیل خوانده می شود حالت پیدا کردنبشر

پایان

اگر به بالا بروید و اکنون اولین تصویر را بررسی کنید ، فکر می کنم می توانید آن را درک کنید. مهم نیست که از کدام حالت استفاده می کنید ، مهمترین چیز این است که زمان جستجو است O(logn)بشر اگر یک آرایه مرتب شده بسیار looooong برای جستجو دارید ، و Array.find خیلی آهسته احساس می شود (که از جستجوی خطی استفاده می کند) ، امتحان کنید Array#bsearch، شما آن را دوست خواهید داشت! ❤

نوشته های مشابه

دیدگاهتان را بنویسید

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

دکمه بازگشت به بالا