সংক্ষেপে
দেখে মনে হচ্ছে আপনার সমস্যার দ্রুত সমাধান হ'ল একটি আরইজিএক্স, বা একটি এফএসএ (সসীম রাষ্ট্র অটোমেটন) সংজ্ঞায়িত করা, যা নথির সমস্ত সম্ভাব্য সূচনাকে স্বীকৃতি দেয় (মিথ্যা ধনাত্মক মঞ্জুরি দেওয়া হয়, এটি আসলে কোনও দস্তাবেজের সাথে মিলে না)। তারপরে আপনি যে জায়গাটি কোনও ত্রুটি দিয়ে কোনও দস্তাবেজ শুরু করতে পারে তার পরের জায়গাটি সনাক্ত করতে আপনি আপনার ইনপুটটিতে এটি খুব দ্রুত চালাতে পারেন। এটি কোনও দস্তাবেজ শুরুর জন্য কয়েকটি ভ্রান্ত অবস্থান তৈরি করতে পারে তবে তারা পার্সার দ্বারা স্বীকৃত হবে এবং ত্যাগ করা হবে।
সুতরাং ফাইনাইট স্টেট অটোমেটন আপনার যে পার্সার নামটি সন্ধান করেছিলেন তা হতে পারে। :)
সমস্যাটি
ব্যবহারিক সমস্যাটি বোঝা সর্বদা কঠিন, বিশেষত যখন শব্দভান্ডারটির অনেকগুলি ব্যাখ্যা থাকতে পারে। পার্স ফরেস্ট শব্দটি কনটেক্সট-ফ্রি (সিএফ) এর জন্য বেশ কয়েকটি পার্স-বৃক্ষ বিশিষ্ট বাক্যগুলি বিশ্লেষণের জন্য তৈরি করা হয়েছিল (আফাইক)। এটি বাক্যগুলির একটি জাল ভাগ করার জন্য, বা অন্যান্য ধরণের ব্যাকরণের ক্ষেত্রে কিছুটা সাধারণ করা যেতে পারে। অতএব আর্লি, জিএলআর, মারপা এবং ডেরিভেটিভ পার্সার (সমস্ত আরও অনেক) সম্পর্কে সমস্ত উত্তর যা এই ক্ষেত্রে প্রাসঙ্গিক ছিল না।
তবে আপাতদৃষ্টিতে এটি আপনার মনে কী নয়। আপনি একটি অনন্য স্ট্রিং পার্স করতে চান যা দ্ব্যর্থহীন নথির ক্রম, এবং প্রত্যেকের জন্য একটি পার্স-ট্রি , বা কোনও ধরণের কাঠামোগত উপস্থাপনা পেতে চান, যেহেতু আপনি প্রকৃতপক্ষে আপনার নথির বাক্য গঠনটি কীভাবে সংজ্ঞায়িত করা হয়েছে, যেখানে এটি থেকে দাঁড়িয়েছে তা বলছেন না ভাষার একটি আনুষ্ঠানিক দৃষ্টিভঙ্গি। আপনার কাছে যা আছে তা হল একটি অ্যালগরিদম এবং সারণী যা কোনও নথির শুরুতে পার্সিং কাজ করবে job তাই হোক।
আসল সমস্যাটি হ'ল আপনার দস্তাবেজের প্রবাহে যথেষ্ট আবর্জনা রয়েছে যা নথিগুলি পৃথক করে। এবং মনে হচ্ছে আপনার অসুবিধাটি হ'ল এই আবর্জনাটি দ্রুত পর্যাপ্ত স্ক্যান করা। আপনার বর্তমান কৌশলটি শুরুতে শুরু করা এবং প্রথম অক্ষরটি থেকে স্ক্যান করার চেষ্টা করুন এবং আপনি যখন পুরো ডকুমেন্টটি স্ক্যান না করেন ততক্ষণ পরবর্তী অক্ষরটি পুনরায় চালু করতে যান। তারপরে আপনি ডকুমেন্টটি কেবল স্ক্যান করার পরে প্রথম অক্ষরটি থেকে পুনরায় উল্লেখ করলেন।
এটি তার উত্তরের দ্বিতীয় অংশে @amon দ্বারা প্রস্তাবিত সমাধানও ।
এটি খুব দ্রুত সমাধান নাও হতে পারে (আমার কাছে পরীক্ষার কোনও উপায় নেই), কারণ এটি সম্ভবত সম্ভাব্য নয় যে পার্সার কোডটি কোনও নথির শুরুতে খুব দক্ষতার সাথে শুরু হওয়ার জন্য অনুকূলিত হয়েছিল। সাধারণ ব্যবহারে এটি কেবল একবার এটি করে, যাতে এটি অপ্টিমাইজেশনের দৃষ্টিকোণ থেকে গরম স্থান না হয়। অতএব, এই সমাধানের সাথে আপনার মাঝারি সুখ খুব অবাক হওয়ার মতো নয়।
সুতরাং আপনার যা প্রয়োজন তা হল একটি অ্যালগরিদম যা দ্রুত কোনও ডকুমেন্টের শুরুটি খুঁজে পেতে পারে যা প্রচুর জঞ্জালের সাথে শুরু হয়। এবং আপনি ভাগ্যবান: এই জাতীয় অ্যালগরিদমের উপস্থিতি রয়েছে। এবং আমি নিশ্চিত যে আপনি এটি জানেন: এটি একটি রেগেক্সের জন্য অনুসন্ধান বলা হয়।
সহজ সমাধান
আপনাকে যা করতে হবে তা হ'ল এই নথিগুলি কীভাবে শুরু হয় তা অনুসন্ধান করার জন্য আপনার দস্তাবেজের স্পেসিফিকেশন বিশ্লেষণ করা। আমি কীভাবে ঠিক তা বলতে পারি না, কারণ আমি নিশ্চিত না যে কীভাবে তাদের সিনট্যাক্সের স্পেসিফিকেশন আনুষ্ঠানিকভাবে সংগঠিত হয়। সম্ভবত তারা সমস্ত সীমাবদ্ধ তালিকা থেকে কিছু শব্দ দিয়ে শুরু করে, সম্ভবত কিছু বিরামচিহ্ন বা সংখ্যার সাথে মিশ্রিত হয়। এটি আপনার পরীক্ষা করার জন্য।
আপনাকে যা করতে হবে তা হল একটি সীমাবদ্ধ রাষ্ট্র অটোমেটন (এফএসএ) বা সমতুল্যভাবে বেশিরভাগ প্রোগ্রামারদের জন্য একটি নিয়মিত এক্সপ্রেশন (আরজিইএক্স) যা কোনও নথির প্রথম কয়েকটি অক্ষর সনাক্ত করতে পারে: আরও বেশি ভাল, তবে এটি খুব বেশি হওয়ার দরকার নেই বৃহত্তর (যেহেতু সময় এবং স্থান নিতে পারে)। আপনার ডকুমেন্টগুলির স্পেসিফিকেশন থেকে এটি করা তুলনামূলকভাবে সহজ হওয়া উচিত এবং আপনার ডকুমেন্টগুলির স্পেসিফিকেশন পড়া কোনও প্রোগ্রামের সাহায্যে স্বয়ংক্রিয়ভাবে এটি করা যেতে পারে।
একবার আপনি আপনার রেজিএক্সপ্যাক্স তৈরি করার পরে, আপনার প্রথম (বা পরবর্তী) নথির শুরুতে খুব দ্রুত পেতে আপনার ইনপুট স্ট্রিমে এটি চালাতে পারেন:
আমি ধরে নিই:
- docstart
সমস্ত ডকুমেন্টের শুরুর সাথে মিলে যায় এমন একটি রেইজেক্স
- search(regex, stream)
এমন একটি ফাংশন stream
যা মিলে যায় এমন একটি স্ট্রিংয়ের সন্ধান করে regex
। এটি যখন ফিরে আসে, প্রথম মিলনের সাবস্ট্রিংয়ের শুরুতে স্ট্রিমটি তার প্রত্যয়টি সাবস্ট্রিম থেকে কমে যায় বা খালি প্রবাহে কোনও মিল খুঁজে পাওয়া যায় না।
- parse(stream)
স্ট্রিমের শুরু থেকে কোনও দস্তাবেজকে বিশ্লেষণ করার চেষ্টা করে (এর কী বাকী থাকে) এবং যে কোনও ফর্ম্যাটে পার্স ট্রি প্রদান করে বা ব্যর্থ হয়। যখন এটি ফিরে আসে, প্রবাহিত দস্তাবেজটির অবিলম্বে অবস্থানটি শুরু করে স্ট্রিমটিকে তার প্রত্যয়টি সাবস্ট্রিম এ হ্রাস করা হয়। পার্স ব্যর্থ হলে এটি ব্যতিক্রমকে কল করে।
forest = empty_forest
search(docstart, stream)
while stream is not empty:
try:
forest = forest + parse(stream)
except
remove first character from stream
search(docstart, stream)
নোট করুন যে প্রথম অক্ষরটি অপসারণ করা প্রয়োজনীয় যাতে পরবর্তী অনুসন্ধানে আবার একই মিল খুঁজে না পায়।
অবশ্যই, স্ট্রিমটি ছোট করা একটি চিত্র। এটি কেবল স্রোতে একটি সূচক হতে পারে।
একটি চূড়ান্ত দ্রষ্টব্য হ'ল যতক্ষণ না এটি সমস্ত সূচনা স্বীকৃতি দেয় ততক্ষণ আপনার রেজেক্স খুব বেশি নির্ভুল হওয়ার প্রয়োজন নেই। যদি এটি মাঝেমধ্যে একটি স্ট্রিংকে স্বীকৃতি দেয় যা কোনও নথির সূচনা হতে পারে না (মিথ্যা ধনাত্মক), তবে একমাত্র জরিমানা হ'ল পার্সারের কাছে একটি অকেজো কল cost
সুতরাং এটি সম্ভবত কার্যকর যদি রেজেক্স সহজতর করতে সাহায্য করতে পারে।
দ্রুত সমাধানের সম্ভাবনা সম্পর্কে
উপরের সমাধানটি বেশিরভাগ ক্ষেত্রে বেশ ভালভাবে কাজ করা উচিত। তবে, যদি আপনার কাছে প্রক্রিয়াজাতকরণের জন্য সত্যিই প্রচুর আবর্জনা এবং টেরাবাইট থাকে, তবে অন্যান্য অ্যালগরিদমগুলি দ্রুত চলতে পারে।
ধারণাটি বয়ের-মুর স্ট্রিং অনুসন্ধান অ্যালগরিদম থেকে নেওয়া । এই অ্যালগরিদম খুব দ্রুত একটি একক স্ট্রিংয়ের জন্য একটি স্ট্রিম সন্ধান করতে পারে কারণ এটি স্ট্রিমের স্ট্রাকচারাল বিশ্লেষণ ব্যবহার করে বেশিরভাগ স্ট্রিমের পড়া পড়া ছেড়ে যায়, এমনকি তাদের দিকে না তাকিয়ে টুকরো টুকরো করে uses এটি একটি একক স্ট্রিংয়ের জন্য দ্রুততম অনুসন্ধানী অ্যালগরিদম।
তীব্র অসুবিধাটি হ'ল এটির রেজিেক্সের অনুসন্ধানের সাথে এর রূপান্তরটি, একটি একক স্ট্রিংয়ের পরিবর্তে খুব সূক্ষ্ম বলে মনে হয় এবং আপনি যে রেজিগের বৈশিষ্ট্যগুলি বিবেচনা করছেন তার উপর নির্ভর করে এটি কাজ করতেও পারে না। এটি পরিবর্তিত হতে পারে আপনি যে দস্তাবেজগুলি বিশ্লেষণ করছেন তার সিনট্যাক্সের উপর। তবে আমার উপর খুব বেশি বিশ্বাস করবেন না যেহেতু আমার যে দস্তাবেজগুলি পাওয়া গেছে সেগুলি মনোযোগ সহকারে পড়ার মতো সময় আমার হাতে নেই।
আমি ওয়েবে একটি বা দুটি পয়েন্টার পেয়ে যাচ্ছি যা স্পষ্টতই একটি রেফার্ড গবেষণা পত্র হিসাবে অন্তর্ভুক্ত রয়েছে তবে আপনার দৃ strong় পারফরম্যান্সের সমস্যা থাকলেই আপনার এটিকে আরও অনুমানমূলক, সম্ভবত গবেষণা হিসাবে বিবেচনা করা উচিত। এবং সম্ভবত এটির কোনও শেল্ফ প্রোগ্রাম নেই।