Map(c++ STL) [Lec – 2.2]

রিফাত যথেষ্ট ভুলোমনা একজন মানুষ। অনেকেই ওর এই দূর্বলতার সুযোগ নেয়। যারা ওর কাছে টাকা পায় – তারা সঠিক সংখ্যার চেয়ে যথেষ্ট বাড়িয়ে বলে। আবার যারা ওর থেকে টাকা ধার নিয়েছে/নেয় তারা বলে – “অনেক আগেই তো দিয়ে দিয়েছি”। এর জন্য বাসায় ওকে অনেক বকা খেতে হয়।

এখন রিফাতকে সাহায্য করার জন্য তোমার একটা প্রোগ্রাম লিখতে হবে। যেখানে রিফাত কার কাছে কত টাকা পায় আর রিফাতের কাছে কে কত টাকা পায় সেই হিসেব সহজেই যে কারো নাম ইনপুট দিলেই দেখা যাবে।

উপরের ঘটনাটা এই নির্দিষ্ট বিষয় শেখার জন্য এবং বুঝার জন্য সবচেয়ে সহজ এবং ভালো মনে হয় আমার কাছে। কারণ এটা খুবই বাস্তব। সেই দুঃখের ঘটনায় না গিয়ে আমরা ফিরে আসি এই প্রোগ্রামটা কিভাবে করা যায়? নিজে থেকে কিছুক্ষণ চিন্তা করা যাক…..

আমি শুরুর দিকে এই রকম একটা প্রবলেম পেয়েছিলাম uva তে তখন যেভাবে চিন্তা করেছিলাম সেটাই বর্ণনা করি প্রথমে, কারণ বেশিরভাগ মানুষই এইভাবে চিন্তা করবে প্রথমদিকে(যারা map সম্পর্কে জানে না)।

দুইটা Array চিন্তা করি – একটাতে নামের হিসেব থাকবে আরেকটাতে টাকার।

string  name[100];

int takarHisheb[100];

(ধরে নিচ্ছি রিফাত সর্বোচ্চ ১০০ জন মানুষকে চিনে)

name[0] =  “Asif”  |  takarHisheb[0] = – 80

name[1] =  “Aarafat”  |  takarHisheb[1] = 500

name[2] =  “Alvi”  |  takarHisheb[2] = 0

…..

উপরের এই কয়েক লাইন থেকে কিছু কি বুঝতে পারা যাচ্ছে? আমি ইন্ডেক্সকে কমন রাখছি দুই জায়গায়। name[0] = “Asif” আছে আর takarHisheb[0] = -80 আছে, তার মানে আসিফ আমার কাছে ৮০ টাকা পাবে। মাইনাস দ্বারা বুঝাচ্ছি আমার কাছে কেউ পাবে আর প্লাস মানে আমি কারো কাছে পাবো। Asif  নামটা name এরেতে যেই ইন্ডেক্সে আছে সেই একই ইন্ডেক্সে takarHisheb  array তে টাকার হিসেবটা রাখছি।

এখন কেউ যখন রিফাতের কাছে এসে টাকা চাবে রিফাত তাঁর নাম জিজ্ঞেস করে প্রোগ্রামে ইনপুট দিবে – প্রোগ্রামে নামের array তে প্রথমে সেই নাম খুঁজবে। যদি না পায় তার মানে তাঁর সাথে রিফাতের কোনদিন পরিচয়ই হয়নি (ধরে নিচ্ছি)। এই খোজার কাজটা খুব সহজ লুপ চালিয়ে, if() কন্ডিশনের মাধ্যমে করা যাবে। যদি নামের অস্তিত্ব পায় তাহলে সেই ইন্ডেক্স দিয়ে takarHisheb Array থেকে তথ্য নিয়ে আসবে।

খুঁজতে যাওয়ার যেই সময় বারবার লাগছে সেটা বিবেচনায় না নিলাম আপাতত। এখন যদি আমাকে বলে টাকার হিসেবে sort করে রিফাতকে পুরো হিসেব দেখাতে তখন কি হবে? সব ইন্ডেক্সের হিসেবই তো ওলোট-পালোট হয়ে যাবে।

এইবার আসি map বাবাজির কাছে, ও খুবই দারুন জিনিস। ওর ইন্ডেক্সের পদ্ধতিটা ভিন্ন, আমি ওকে যেইভাবে ইন্ডেক্সিং করতে বলবো সেইভাবেই ও “জো হুকুম” বলে কাজ করবে।

সাধারণত আমরা যখন array ডিক্লেয়ার করে কোন ভ্যালু জানতে চাই, আমাদের তখন ইন্ডেক্স জানা থাকতে হয় যা যেকোন ডাটা-টাইপের এরের জন্য 0 থেকে শুরু হয়। double, int, float, boolean, string সবকিছুর জন্যই যা সত্য। map এর ক্ষেত্রে আমি string কে ইন্ডেক্স হিসেবে ব্যবহার করতে পারি।

map  variable_name;

এইভাবে ডিক্লেয়ার করতে হয় mpa । index টাকেই এখানে key বলা হচ্ছে, সেটার ডাটা টাইপটা আমি উল্লেখ করে দিতে হয়, আর কি ধরনের ভ্যালু রাখতে চাই সেই key এর বিপরীতে সেটাও উল্লেখ করে দিতে হবে।

Example :

map<string,int> mp;

map<string, vector > mp;

map<int, vector > mp;

etc.

map

ম্যাপে কিভাবে ভ্যালু রাখতে হয় তা ছবিতে দেখতে পাচ্ছি, একটা আমি নিজে থেকে কিভাবে রাখবো আরেকটা হলো ইনপুট নিয়ে কিভাবে রাখবো।

count নামে আরেকটা ফাংশন আছে map এর যেটা দিয়ে জানা যায় কোন key কি ম্যাপে আছে নাকি নাই।

mp.count(“Rifat”); এইটা লিখলে কি উত্তর পাওয়া উচিত? উপরের কোডের ভিত্তিতে? ওর কাছে তো Rifat নামের কোন ইনফো নাই, সুতরাং false রিটার্ন করবে(return type boolean)।

আর একটা তথ্য আগে দেয়া হয় নি – আমরা যেই ম্যাপ নিয়ে কাজ করছি তা key এর ভিত্তিতে sorted (ascending order)থাকবে। মানে নামগুলো যদি – Arafat, Rifat, Himadri হয় ম্যাপের প্রথমে Arafat -> Himadri -> Rifat এই হিসেবে থাকবে।ও নিজে থেকেই এই কাজটা করে থাকে।

এইবার আসি আরেকটা গুরুত্বপুর্ণ ব্যাপারে। সাধারণ এরে তো আমরা for লুপে 0 থেকে size পর্যন্ত iterate করি, এখানে কি করবো? এখানে তো ইন্ডেক্সিং ঐ রকম এরের মতো না।

এখানে একটু ভিন্ন,

map<string,int>::iterator it;

এখানে এঙ্গুলার ব্র্যাকেটের ভিতরের ডাটা টাইপটা, আমার ডিক্লেয়ার করা map এর সাথে হুবহু মিল রেখে লিখতে হবে।

এটা কি? এভাবে চিন্তা করো তুমি একটা লোক ঠিক করছো যাকে দিয়ে তুমি map এর এই প্রান্ত(শুরু) থেকে শেষ পর্যন্ত সব ভ্যালুগুলো টোকাবা। তোমাকে আপাতত জানতে হবে না ও কিভাবে কাজটা করবে, তুমি এতোটুকু শুধু জানো যে ও তোমাকে কাজটা করে দিবে।

it হচ্ছে তোমার ঠিক করা লোকটার নাম, ওর পদবী হচ্ছে iterator যার সামনে দুইটা কোলন আছে।

mapIter

ছবিতে iterator এর ব্যবহার দেখা যাচ্ছে।it = mp.begin() দিয়ে it কে একেবারে প্রথম থেকে শুরু করতে বলছি, it != mp.end() দিয়ে বুঝাচ্ছি যতক্ষণ না একেবারে শেষ প্রান্তে পৌছায় ততক্ষণ পর্যন্ত লুপ চলতে বলছি। আর it এক এক করে বাড়াচ্ছি ম্যাপে পরের ঘরে যাওয়ার জন্য। এখানে it->first দ্বারা key টা আমি নিচ্ছি আর it->second দ্বারা ওর বিপরীতে যে ভ্যালু রাখা আছে তা নিচ্ছি। এই নেয়া মানে map থেকে আমি একেবারে নিয়ে নিচ্ছি না, দেখছি। এরের ক্ষেত্রে যেমন ভ্যালু নিয়ে প্রিন্ট করি অথবা কাজ করি লজিক অনুযায়ী।

আর আউটপুটটা খেয়াল করি একটুঃ

mapItOutput

ইনপুট যেভাবেই দি-ই না কেন আমি, ও key এর ভিত্তিতে সাজিয়ে রাখবে।

মোটামোটি এতোটুকু জানাই যথেষ্ট, আর কোন কিছু জানতে হলে গুগল করলে নিমিষেই হাতের নাগালে পাওয়া যাবে।

Problems to try –

Uva – 10226,  10282, 10295, 417, 484.

Happy Coding 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s