- محدودیت زمان: ۱ ثانیه
- محدودیت حافظه: ۲۵۶ مگابایت
در خانهی مشهور شماره ۲۲۱ بیکر استریت، جاناتان کولمز، یک برنامهنویس با استعداد و دستیار وفادارش دکتر واتسون، به دنبال حل یک معمای جدید هستند. یک روز وقتی که جاناتان به دفترچهی پوشهدار خود مراجعه میکند، با اسنادی مرموز و عجیب مواجه میشود.
این اسناد به زبان انگلیسی نوشته شدهاند و به نظر میرسد برای نظریهپردازی دربارهی یک پروندهی مخفی تهیه شدهاند. جاناتان و دکتر واتسون، با تصمیم به حل این معما، به ساختن ابزاری سریع و قدرتمند میپردازند که به آنها کمک میکند تا اطلاعات مورد نیاز خود را از متون مرموز استخراج کرده و معمایی که پیش رویشان قرار دارد را حل نمایند.
گام اول: پیشپردازش اسناد
اولین گام، پیشپردازش متون اسناد است. این پیادهسازی باید شامل موارد زیر باشد:
تبدیل متن به حروف کوچک
برای جلوگیری از مشکلات مربوط به حساسیت به بزرگی و کوچکی حروف، همه حروف موجود در متن باید به حروف کوچک تبدیل شوند.
برای مثال متن سند پیش از پردازش:
پس از این پردازش به متن زیر تبدیل خواهد شد:
پاکسازی متن
هرگونه کاراکتر غیر از حروف انگلیسی و اعداد که برای جستجوی متنی اهمیتی ندارند، باید حذف شوند.
برای مثال متن سند پیش از پردازش:
پس از این پردازش به متن زیر تبدیل خواهد شد:
حذف کلمات توقفی
کلمات توقفی شامل موارد زیر هستند که در جستجوها نادیده گرفته میشوند و باید از متن حذف شوند:
برای مثال متن پیش از پردازش:
پس از این پردازش به متن زیر تبدیل خواهد شد:
حذف فاصلههای اضافی
نیاز است هرگونه فاصله اضافی بین کلمات حذف شود.
برای مثال متن پیش از پردازش:
پس از این پردازش به متن زیر تبدیل خواهد شد:
گام دوم: طراحی Inverted Index
ساختار داده Inverted Index، ساختاری است که امکان نگهداری اطلاعات برای جستجوی سریع متنی را فراهم میکند. در ادامه با این ساختار داده بیشتر آشنا میشوید.
ایجاد لیست کلمات
در این مرحله، باید تمامی کلمات موجود در هر سند را شناسایی کرده و لیستی از این کلمات ایجاد کنیم. این لیست، پایهای برای ساخت Inverted Index است.
برای مثال در سند زیر:
لیست کلمات به این شکل خواهد بود:
ایجاد Inverted Index
در این مرحله، یک دیکشنری ایجاد میشود که کلیدهای آن کلمات موجود در لیست کلمات هستند و مقادیر آنها لیستی از شماره اسنادی است که هر کلمه در آنها ظاهر شده است.
برای مثال دو سند پیشپردازش شده زیر را در نظر بگیرید:
بنابراین Inverted Index به این شکل خواهد بود:
همانطور که میبینید، کلمه halis
هم در سند 1 و هم در سند 2 وجود دارد؛ در حالی که کلمه please
تنها در سند 1 و کلمه code
تنها در سند 2 وجود دارند.
نکته مهم: Inverted Index از روی اسناد پیشپردازش شده ایجاد میشود.
بازیابی اسناد
اکنون میتوانیم به کمک ساختار داده ایجاد شده، اسناد دلخواه را بازیابی کنیم.
برای مثال Inverted Index زیر را درنظر بگیرید:
میخواهیم بدانیم کلمات halis
و watson
همزمان در چه اسنادی آمدهاست. برای این منظور، کافی است اشتراک شماره اسناد برای این دو کلمه را بررسی کنیم:
همانطور که میبینید، میتوان نتیجه گرفت کلمات halis
و watson
همزمان در سند 1 آمده اند.
گام سوم: جستجوی متنی
در این گام، کوئریهایی طراحی میشوند که به کمک آنها میتوان جستجوی متنی پیشرفته انجام داد و شماره اسناد مربوطه را بازیابی کرد. ساختار این کوئریها با فرمت JSON
است که در ادامه معرفی خواهند شد.
کوئریهای فرزند
کوئری match
match
با استفاده از این کوئری، اسنادی که شامل یک عبارت مشخص هستند، بازیابی میشوند.
در مثال بالا، اسنادی که شامل عبارت john watson
هستند بازیابی میشوند؛ یعنی این دو کلمه پشت سر هم در متن پیش پردازش شده سند وجود داشته باشد.
کوئری all
all
با استفاده از این کوئری، اسنادی که شامل تمام عبارات هستند، بازیابی میشوند.
در مثال بالا، اسنادی که شامل هر دو عبارت moriarty
و john watson
هستند بازیابی میشوند.
کوئری any
any
با استفاده از این کوئری، اسنادی که شامل حداقل یکی از عبارات هستند، بازیابی میشوند.
در مثال بالا، اسنادی که شامل حداقل یکی از عبارتهای moriarty
یا john watson
باشند بازیابی میشوند.
توجه: منظور از عبارت، یک یا چند کلمه با حروف کوچک است که با فاصله از هم جدا شدهاند.
کوئریهای والد
کوئری and
and
با استفاده از این کوئری، اسنادی بازیابی میشوند که با تمام از کوئریهای فرزند به طور همزمان مطابقت دارند.
در مثال بالا، اسنادی بازیابی میشوند که شامل هر سه کلمهی rainy
، sherlock
و death
باشند.
یک نمونه کوئری دیگر شامل and
:
کوئری or
or
با استفاده از این کوئری، اسنادی بازیابی میشوند که با حداقل یکی از کوئریهای فرزند مطابقت داشته باشد.
در مثال بالا، اسنادی بازیابی میشوند که یا شامل عبارت rainy night
باشند، یا اینکه همه عبارات sherlock holmes
، dr john watson
و moriarty
در آن اسناد آمده باشد، و یا اینکه حداقل یکی از کلمات death
یا boold
در آن اسناد آمده باشد.
کوئری not
not
با استفاده از این کوئری، تمام اسنادی که با کوئری فرزند مطابقت نداشته باشند بازیابی میشوند.
در مثال بالا، اسنادی بازیابی میشوند که هر دو عبارت knife
و gun
همزمان در آن اسناد نیامده باشد.
نکات تکمیلی (مهم)
نکته اول
کوئریهای والد، خود نیز میتوانند فرزند کوئری والد دیگری باشند.
نکته دوم
در ریشه کوئری، ممکن است متغیر size
بیاید که نشان دهنده حداکثر تعداد اسنادی است که باید بازیابی شوند. درصورتی که اندازه مشخص نشده بود، همه نتایج بازیابی میشوند.
جمعبندی
هدف این است که ابزاری ساخته شود تا متون اسناد را پیش پردازش کرده، سپس ساختار داده Inverted Index ایجاد شود. در نهایت به کمک این ساختار داده جهت افزایش سرعت جستجو، کوئریهایی با هدف بازیابی اسناد مختلف، پردازش شوند.
توجه: لازم است اصول برنامه نویسی شیءگرا، کد تمیز و اصول SOLID تا حد ممکن در نظر گرفته شود.
توجه: امکان پیادهسازی بخشی از سوال و کسب نمره آن بخش از سوال وجود دارد.
توجه: تنها یک فایل شامل کدهای نوشته شده آپلود کنید.
ورودی
ورودی شامل خط است. در خط اول، تعداد سندها، داده میشود. در خط بعدی، در هر خط متن سند ام داده میشود. سپس، عدد (تعداد کوئریها) آمده است. در خط بعدی، در هر خط یک کوئری با فرمت JSONPath
میآید.
راهنمایی: برای تبدیل کوئری از فرمت JSONPath به فرمت JSON، میتوانید از این کدها استفاده نمایید.
کد Java
کد C#
کد C++
خروجی
در خروجی به ازای هر کوئری، شماره اسنادی که بازیابی میشوند را به ترتیب شماره اسناد از کوچک به بزرگ با فاصله در یک خط چاپ کنید.
در صورتی که هیچ سندی در نتیجه اجرای کوئری پیدا نشد، عبارت NO RESULT
را چاپ کنید.
مثال
ورودی نمونه ۱
خروجی نمونه ۱
توضیحات نمونه ۱
پس از مرحله پیشپردازش، اسناد به صورت زیر خواهند بود:
همچنین کوئریها پس از تبدیل به شکل زیر خواهند بود:
- در کوئری اول، به دنبال اسنادی هستیم که عبارت
mystery
در آنها وجود دارد. این عبارت تنها در اسناد 2 و 3 آمده است. - در کوئری دوم، اسنادی را میخواهیم بازیابی کنیم که حداقل یکی از عبارات
mystery
یاsolution
در آن اسناد آمده است. عبارتmystery
در سند 2 و 3 و عبارتsolution
در سند 1 آمده است. - در کوئری سوم، دنبال اسنادی میگردیم که هر دو عبارت
mystery
وclue
در آن اسناد آمده باشد. سند 3 هردوی این عبارات را دارا است.
ورودی نمونه ۲
خروجی نمونه ۲
توضیحات نمونه ۲
پس از مرحله پیشپردازش، اسناد به صورت زیر خواهند بود:
همچنین کوئریها پس از تبدیل به شکل زیر خواهند بود:
- در کوئری اول، اسنادی را میخواهیم بازیابی کنیم که حداقل یکی از عبارات
watson
یاholmes
در آن اسناد آمده است. عبارتwatson
در همه اسناد به جز اسناد 6 و 7 آمده است. از طرفی عبارتholmes
در سند 6 و 7 هم دیده میشود. بنابراین همه اسناد بازیابی میشوند. - کوئری دوم همانند کوئری اول است با این تفاوت که
size
برابر 6 است. بنابراین تنها 6 سند اول بازیابی میشوند. - در کوئری سوم، دنبال اسنادی میگردیم که حتما عبارت
learn
در آن اسناد وجود داشته باشد، به علاوه اینکه حداقل یکی از عباراتwatson
یاholmes
هم وجود داشته باشد. عبارتwatson
وholmes
در کنار عبارتlearn
تنها در سند 3 آمدهاند.
ورودی نمونه ۳
خروجی نمونه ۳
توضیحات نمونه ۳
پس از مرحله پیشپردازش، اسناد به صورت زیر خواهند بود:
همچنین کوئریها پس از تبدیل به شکل زیر خواهند بود:
- در کوئری اول، به دنبال اسنادی هستیم که عبارت
little things
در آنها وجود دارد. کلماتlittle
وthings
تنها در سند 2 پشت سر هم دیده میشوند. - کوئری دوم نیز مشابه کوئری اول است، با این تفاوت که به دنبال 3 کلمه پشت سر هم هستیم.
- در کوئری سوم، عبارت
common rare
در هیچ سندی دیده نمیشود.
ورودی نمونه ۴
خروجی نمونه ۴
ارسال پاسخ برای این سؤال