ইটারেটর এবং অ্যালগরিদম (Iterators & Algorithms)
এক সর্বজনীন বা ইউনিভার্সাল রিমোট (The Universal Remote)
ধরুন আপনার কাছে একটি টিভি (TV), একটি ব্লু-রে প্লেয়ার (Blu-ray player) এবং একটি সাউন্ড সিস্টেম (sound system) রয়েছে — এদের প্রত্যেকটিই আবার ভিন্ন ভিন্ন ব্র্যান্ডের (different brand)। এখন এই তিনটি আলাদা আলাদা রিমোটের ব্যবহার শেখার বদলে, আপনি চাইলে এমন একটি ইউনিভার্সাল বা সর্বজনীন রিমোট (universal remote) নিতে পারেন, যা এই তিনটির সাথেই সমানভাবে কাজ করবে।
আর সি++ (C++)-এ এই ইটারেটরগুলোও (iterators) ঠিক একই কাজ করে থাকে। আপনার ডেটাগুলো একটি vector, একটি map, একটি set, কিংবা একটি list-এর যেখানেই থাকুক না কেন, এই ইটারেটরগুলো মূলত আপনাকে এখানকার যেকোনো উপাদান বা এলিমেন্টগুলোতে (elements) যাওয়ার জন্য শুধুমাত্র একটি নির্দিষ্ট ইন্টারফেস (one consistent interface) প্রদান করে। আর এখানকার অ্যালগরিদমগুলো (algorithms) হলো ওই রিমোটে প্রি-প্রোগ্রাম (pre-programmed) করা বিভিন্ন বোতামের (buttons) মতো — যেমন শর্ট (sort), সার্চ (search), ট্রান্সফর্ম (transform), কাউন্ট (count) ইত্যাদি — যা সব সময়ই কাজ করার জন্য প্রস্তুত (ready to go) থাকে।
begin() এবং end()
প্রতিটি এসটিএল কন্টেইনারই (STL container) মূলত দুটি প্রধান ইটারেটর (iterators) প্রদান করে থাকে:
begin()— এটি মূলত এর প্রথম (first) এলিমেন্টটির দিকে পয়েন্ট (points) করে থাকেend()— এটি মূলত এর ওই সর্বশেষ এলিমেন্টের ঠিক পরের (one past the last) ঘরটিকে পয়েন্ট (points) করে (এটি মূলত একটি সেন্টিনেল বা sentinel, এটি কোনো আসল এলিমেন্ট বা real element নয়)
এখানকার এই হাফ-ওপেন রেঞ্জটিই বা [begin, end) রেঞ্জটিই হলো এখানকার যেকোনো অ্যালগরিদমের মূল ভিত্তি (foundation)। এর মানে হলো: "এখান থেকে শুরু করো, এবং ঠিক এখানকার আগেই (before) থামো (stop)।"
ইটারেটর ক্যাটাগরিগুলো (Iterator Categories)
সব ইটারেটর এক রকম হয় না (Not all iterators are equal)। এগুলো মূলত ভিন্ন ভিন্ন হায়ারার্কি (hierarchy) বা পর্যায়ক্রম তৈরি করে থাকে:
- ইনপুট (Input) — এগুলোকে শুধু একবার সামনের দিকে (forward) পড়া (Read) যায় (যেমন কোনো স্ট্রিম বা stream থেকে কিছু পড়া)
- আউটপুট (Output) — এগুলোকে শুধু একবার সামনের দিকে (forward) লেখা (Write) যায়
- ফরওয়ার্ড (Forward) — এগুলোতে একাধিকবার পড়া/লেখা (Read/write) যায় (যেমন,
forward_list) - বাই-ডিরেকশনাল (Bidirectional) — এগুলো দিয়ে সামনে + পেছনে (Forward + backward) দিকে কাজ করা যায় (যেমন,
list,map,set) - র্যান্ডম অ্যাক্সেস (Random Access) — এগুলো দিয়ে O(1) সময়ের মধ্যে যেকোনো জায়গায় জাম্প (Jump anywhere) করা যায় (যেমন,
vector,deque)
যেকোনো অ্যালগরিদমের (Algorithms) কাজ করার জন্য মূলত একটি সর্বনিম্ন বা মিনিমাম (minimum) ইটারেটর ক্যাটাগরির (iterator category) প্রয়োজন পড়ে। যেমন std::sort-এর জন্য র্যান্ডম অ্যাক্সেস (random access) প্রয়োজন, তাই এটি ভেক্টরগুলোতে (vectors) কাজ করলেও সাধারণ লিস্টগুলোতে (lists) কাজ করে না।
একটি ভেক্টর শর্ট (Sorting) করা
ফাইন্ড (find) এবং কাউন্ট (count)
ট্রান্সফর্ম (transform) — আপারকেসে রূপান্তর বা Convert to Uppercase
অ্যাকুমুলেট (accumulate) — এর যোগফল (Sum) এবং বিভিন্ন কাস্টম ফোল্ড (Custom Fold)
রিমুভ-ইরেজ ইডিওম (The Remove-Erase Idiom)
এটি সি++ (C++)-এর সবচেয়ে গুরুত্বপূর্ণ প্যাটার্নগুলোর (patterns) মধ্যে একটি। std::remove মূলত কোনো কন্টেইনার (container) থেকে সরাসরি কোনো এলিমেন্টকে রিমুভ (remove) বা অপসারণ করে না। এটি মূলত আপনার প্রয়োজনীয় এলিমেন্টগুলোকে বা আপনি যেগুলোকে রাখতে চান (keep) সেগুলোকে শুধু সামনের দিকে সরিয়ে (moves) দেয়, এবং এর নতুন একটি "লজিক্যাল এন্ড (logical end)"-কে বোঝানোর জন্য একটি নতুন ইটারেটর রিটার্ন (returns) করে। এতে এখানকার ওই কন্টেইনারটির (container) সাইজ বা আকার (size) কোনোভাবেই পরিবর্তিত (change) হয় না! তাই একে সত্যিই ছোট (shrink) করার জন্য আপনাকে অবশ্যই erase() ব্যবহার করে কল বা call করতে হবে।
রিমুভ-ইরেজ ইডিওম (Remove-Erase Idiom)
সি++২০ রেঞ্জ প্রিভিউ (C++20 Ranges Preview)
সি++২০ (C++20) মূলত বিভিন্ন অ্যালগরিদমগুলোকে (algorithms) আরও সহজে বা ক্লিনার (cleaner) উপায় ব্যবহার (use) করার জন্য রেঞ্জ (ranges)-এর ধারণাটি নিয়ে এসেছে। এখানে আলাদাভাবে begin() এবং end()-কে পাস (passing) করার বদলে, আপনি চাইলে সরাসরি সম্পূর্ণ কন্টেইনারটিকেই (container) পাস করতে পারবেন:
// পুরোনো নিয়মে (Old way)
std::sort(v.begin(), v.end());
// সি++২০ রেঞ্জ (C++20 ranges)
std::ranges::sort(v);এছাড়াও এই রেঞ্জগুলো মূলত ভিউগুলোকেও (views) সাপোর্ট (support) করে থাকে — এগুলো মূলত অত্যন্ত লেজি বা ধীর (lazy), কম্পোজেবল বা জোড়া লাগানো যায় এমন ট্রান্সফরমেশন (composable transformations), যা ডেটাকে কখনও কপি (copy) করে না। এটিই হলো সি++ (C++) অ্যালগরিদমগুলোর ভবিষ্যৎ (future)।