جاوا اسکریپت خوش زبان قسمت بیست و پنجم
جاوا اسکریپت خوش زبان قسمت بیست و پنجم
بازگشت همیشه فقط یک جایگزین ناکارآمد برای حلقه نیست. برخی از مشکلات واقعاً با بازگشت آسان تر از حلقه حل می شوند. اغلب اینها
مشکلاتی هستند که نیازمند کاوش یا پردازش چندین “شاخه” هستند، هر یک
که ممکن است دوباره به شاخه های بیشتری منشعب شود.
این پازل را در نظر بگیرید: با شروع از عدد 1 و یا به طور مکرر
با جمع کردن 5 یا ضرب در 3 می توان مجموعه ای بی نهایت از اعداد را تولید کرد. چگونه
آیا می خواهید تابعی بنویسید که با یک عدد، دنباله ای از آن را پیدا کند
چنین جمع و ضرب هایی که آن عدد را ایجاد می کند؟
به عنوان مثال، عدد 13 را می توان با ضرب اول در 3 و بدست آورد
سپس 5 را دو بار اضافه می کنیم، در حالی که به هیچ وجه نمی توان به عدد 15 رسید.
در اینجا یک راه حل بازگشتی وجود دارد:
تابع findSolution(target) {
یافتن تابع (جریان، تاریخچه) {
اگر (جاری == هدف) {
تاریخچه بازگشت؛
} else if (current > target) {
بازگشت تهی
}دیگر {
return find(current + 5, `(${history} + 5)`) ||
find(current * 3, `(${history} * 3)`);
}
}
return find(1, “1”);
}
console.log(findSolution(24));
// → (((1 * 3) + 5) * 3)
توجه داشته باشید که این برنامه لزوما کوتاهترین دنباله عملیات را پیدا نمی کند. وقتی اصلاً دنباله ای پیدا کند راضی می شود.
اگر فوراً نحوه عملکرد آن را نبینید اشکالی ندارد. بیایید از طریق آن کار کنیم،
از آنجایی که این یک تمرین عالی در تفکر بازگشتی است.
تابع داخلی پیدا کردن، بازگشت واقعی را انجام می دهد. دو استدلال نیاز دارد:
عدد فعلی و رشته ای که نحوه رسیدن ما به این عدد را ثبت می کند. اگر
راه حلی پیدا می کند، رشته ای را برمی گرداند که نحوه رسیدن به هدف را نشان می دهد. اگر
هیچ راه حلی با شروع از این عدد پیدا نمی شود، آن را null برمی گرداند.
برای انجام این کار، تابع یکی از سه عمل را انجام می دهد. اگر شماره فعلی
شماره هدف است، تاریخ فعلی راهی برای رسیدن به آن هدف است، بنابراین
برگردانده می شود. اگر عدد فعلی بیشتر از هدف باشد، معنی ندارد
در کاوش بیشتر این شاخه زیرا هم جمع و هم ضرب فقط خواهد بود
عدد را بزرگتر کنید، بنابراین null برمیگرداند. در نهایت، اگر ما هنوز در پایین تر از
شماره هدف، تابع هر دو مسیر ممکن را که از جریان شروع می شود، امتحان می کند
شماره را با صدا زدن خود دو بار، یک بار برای جمع و یک بار برای ضرب. اگر
اولین فراخوان چیزی را برمی گرداند که تهی نیست، برگردانده می شود. در غیر این صورت،
فراخوانی دوم صرف نظر از اینکه رشته ای تولید کند یا تهی برگردانده می شود.
برای درک بهتر اینکه چگونه این تابع اثر مورد نظر ما را ایجاد می کند،
بیایید به همه تماسهایی که هنگام جستجو برای یافتن راهحل ایجاد میشوند، نگاه کنیم
برای شماره 13
پیدا کردن (1، “1”)
find(6، “(1 + 5)”)
find(11، “((1 + 5) + 5)”)
find(16، “(((1 + 5) + 5) + 5)”)
خیلی بزرگ
find(33، “(((1 + 5) + 5) * 3)”)
خیلی بزرگ
find(18، “((1 + 5) * 3)”)
خیلی بزرگ
find(3، “(1 * 3)”)
قوانین ارسال دیدگاه در سایت