C++ একই টাইপের এলিমেন্ট একটি নির্দিষ্ট ক্রমে জমা রাখার জন্য বিভিন্ন কন্টেইনার সরবরাহ করে।
নির্দিষ্ট সাইজের কন্টেইনারের জন্য আছে std::array, আর ডায়নামিক রিসাইজিংয়ের সুবিধা নিয়ে আসে std::vector.
অ্যারে বা ভেক্টর ডিক্লেয়ার করার সময় কোন টাইপের এলিমেন্ট ওই কন্টেইনারটি ধারণ করবে তা উল্লেখ করতে হয়। অ্যারেগুলোর ক্ষেত্রে সাইজও দিতে হয়। দুটি কন্টেইনার টাইপ কীভাবে ইনিশিয়ালাইজ করা হয়, তা দেখতে এই উদাহরণগুলো দেখুন:
#include <array>
#include <string>
// std::array<element_type, size> variable_name {list of elements}
std::array<std::string, 3> indie_rock {"yeah", "yeah", "yeah"};
// indie_rock contains the elements "yeah" three times
ভেক্টর সাধারণত বেশি জায়গা নেয়, কারণ ভবিষ্যতে আরও বাড়ার জন্য এরা মেমরি অ্যালোকেট করে। আপনাকে সাইজ উল্লেখ করতে হয় না:
#include <vector>
// std::vector<element_type> variable_name {list of elements}
std::vector<int> countdown {3, 2, 1};
// countdown contains the elements 3, 2 and 1
দ্রষ্টব্য: টেমপ্লেট কনসেপ্টের পেছনের সঠিক কার্যপ্রণালী এখনই জানার দরকার নেই, সিলেবাস ট্রি-তে আরও নিচে এর জন্য আলাদা কনসেপ্ট থাকবে।
ভেক্টর আর অ্যারে, দুটোই নিজেদের এলিমেন্ট অ্যাক্সেস করার জন্য একই ফাংশন ব্যবহার করে।
কন্টেইনারের প্রথম ও শেষ এলিমেন্ট পেতে আপনি মেম্বার ফাংশন front ও back ব্যবহার করতে পারেন।
নির্দিষ্ট এলিমেন্ট অ্যাক্সেস করার জন্য আছে at এবং [] অপারেটর।
countdown[0];
// => 3
countdown.at(2);
// => 1
countdown[1] = 4;
// countdown now contains 3, 4 and 1
indie_rock.back() = "yeahs";
// indie_rock is now "yeah", "yeah", "yeahs"
দ্রষ্টব্য: আপনি যদি এমন কোনো পজিশন বেছে নেন যা আপনার কন্টেইনারের রেঞ্জে নেই, তাহলে
[]আনডিফাইন্ড বিহেভিয়ার তৈরি করতে পারে। আরatফাংশনটি একটি এক্সেপশন ছুড়ে দেবে, যা দীর্ঘমেয়াদে আপনার জীবন সহজ করে দিতে পারে।
যেহেতু vector-এর সাইজ নির্দিষ্ট নয়, তাই এলিমেন্ট যোগ করা বা সরিয়ে ফেলা সম্ভব।
এই কাজের জন্য দুটি কমন ফাংশন হলো emplace_back এবং pop_back.
std::vector<std::string> witches {"Holly", "Alyssa", "Shannen"};
witches.pop_back();
// Shannen is no longer with the witches
witches.emplace_back("Rose");
// Rose has joined the team
মেম্বার ফাংশন empty দিয়ে কন্টেইনার খালি কি না তা যাচাই করতে পারেন।
এলিমেন্টের সংখ্যা জানতে চাইলে size ব্যবহার করতে পারেন।
আপনি একজন শিক্ষক সহকারী, শিক্ষার্থীদের পরীক্ষার খাতা মূল্যায়ন করছেন। ফলাফল হাতে হাতে হিসাব রাখা ক্রমশ ক্লান্তিকর ও ভুলপ্রবণ হয়ে উঠছে। তাই আপনি ঠিক করলেন, ক্লাসের ফলাফল গণনা ও হিসাব করার জন্য কিছু ফাংশন বানিয়ে বিষয়টাকে একটু মজাদার করে তুলবেন।
পরীক্ষার প্রশ্নে আপনি "আংশিক নম্বর" দিতে পারলেও, সামগ্রিক পরীক্ষার স্কোর int হতে হবে।
তাই ক্লাসের স্কোর নিয়ে আর কিছু করার আগে, আপনাকে গ্রেডগুলো একবার দেখে নিতে হবে এবং যেকোনো double স্কোরকে int-এ বদলে ফেলতে হবে।
round_down_scores() ফাংশনটি তৈরি করুন, যা student_scores-এর একটি vector নেয়।
স্কুলগুলো যে রাউন্ডিং চেয়েছে, সেটি হলো দশমিকের পরের অংশ ছেঁটে ফেলা।
আপনার ভাগ্য ভালো, C++ static_cast দিয়ে এক টাইপকে আরেক টাইপে কাস্ট করতে পারে।
double থেকে int-এ static_cast রূপান্তর দশমিকের পরের যেকোনো অঙ্ক কেটে ফেলে।
এই ফাংশনটি ইনপুট vector নেবে এবং এমন একটি নতুন ভেক্টর return করবে যেখানে সব স্কোর int-এ রূপান্তরিত।
std::vector<double> student_scores {90.33, 40.5, 55.44, 70.05, 30.55, 25.45, 80.45, 95.3, 38.7, 40.3};
round_down_scores(student_scores)
// => {90, 40, 55, 70, 30, 25, 80, 95, 38, 40}
একই ফলাফল পাওয়ার আরও উপায় আছে, তবে কাস্ট খুব কমন একটি ব্যাপার।
int new_PI{static_cast<int>(3.14) + static_cast<int>(0.001592653589)};
// new_PI is 3.
পরীক্ষার খাতা মূল্যায়ন করার সময় আপনি লক্ষ্য করলেন, কিছু শিক্ষার্থী আপনার আশানুরূপ ভালো করছে না। কিন্তু আপনি মনোযোগ হারিয়ে ফেলেছিলেন, এবং ঠিক কতজন শিক্ষার্থী তা লিখে রাখতে ভুলে গিয়েছিলেন।
count_failed_students() ফাংশনটি তৈরি করুন, যা student_scores-এর একটি vector নেয়।
এই ফাংশনটি এমন শিক্ষার্থীর সংখ্যা গণনা করবে যাদের পাস করার মতো স্কোর নেই, এবং সেই সংখ্যাটি একটি ইন্টিজার হিসেবে রিটার্ন করবে।
পরীক্ষায় পাস করার জন্য একজন শিক্ষার্থীর স্কোর 40-এর বেশি হতে হবে।
count_failed_students({90,40,55,70,30,25,80,95,38,40});
// => 5
আপনি যে শিক্ষককে সহায়তা করছেন, তিনি সংখ্যাসূচক স্কোরের পাশাপাশি লেটার গ্রেডও দিতে পছন্দ করেন। পরীক্ষায় শিক্ষার্থীরা খুব কমই 100 পায়, তাই "লেটার গ্রেড"-এর নিম্ন সীমাগুলো সর্বোচ্চ প্রাপ্ত স্কোরের ভিত্তিতে হিসাব করা হয়, এবং সর্বোচ্চ স্কোর থেকে <= 40 ফেলের সীমা পর্যন্ত সমানভাবে বাড়তে থাকে।
letter_grades() ফাংশনটি তৈরি করুন, যা পরীক্ষার "সর্বোচ্চ" স্কোরকে প্যারামিটার হিসেবে নেয় এবং প্রতিটি "আমেরিকান স্টাইল" গ্রেড ব্যবধানের নিম্ন স্কোর সীমার একটি array (ভেক্টর নয়) রিটার্ন করে: ["D", "C", "B", "A"]।
/*Where the highest score is 100, and failing is <= 40.
"F" <= 40
41 <= "D" <= 55
56 <= "C" <= 70
71 <= "B" <= 85
86 <= "A" <= 100
*/
letter_grades(100);
// => {41, 56, 71, 86}
/*Where the highest score is 88, and failing is <= 40.
"F" <= 40
41 <= "D" <= 52
53 <= "C" <= 64
65 <= "B" <= 76
77 <= "A" <= 88
*/
letter_grades(88);
// => {41, 53, 65, 77}
আপনার কাছে পরীক্ষার স্কোর অবরোহ ক্রমে আছে, এবং সেই অনুযায়ী শিক্ষার্থীদের নামও (তাদের পরীক্ষার স্কোরের ক্রম অনুসারে সাজানো)। আপনি প্রতিটি শিক্ষার্থীর নাম তাদের পরীক্ষার স্কোরের সাথে মেলাতে চান এবং পুরো ক্লাসের একটি সামগ্রিক র্যাঙ্কিং ছাপতে চান।
student_scores এবং student_names প্যারামিটার নিয়ে student_ranking() ফাংশনটি তৈরি করুন।
student_names vector-এর প্রতিটি শিক্ষার্থীর নাম student_scores vector-এর সংশ্লিষ্ট স্কোরের সাথে মিলিয়ে দিন।
আপনি ধরে নিতে পারেন যে প্রতিটি আর্গুমেন্ট vector সর্বোচ্চ স্কোর থেকে সর্বনিম্ন স্কোর পর্যন্ত সাজানো।
ফাংশনটি <rank>. <student name>: <student score> ফরম্যাটে স্ট্রিং-এর একটি vector রিটার্ন করবে।
std::vector<int> student_scores {100, 99, 90, 84, 66, 53, 47};
std::vector<std::string> student_names {"Joci", "Sara","Kora","Jan","Indra","Bern", "Fred"};
student_ranking(student_scores, student_names)
// =>
// {"1. Joci: 100", "2. Sara: 99", "3. Kora: 90", "4. Jan: 84", "5. Indra: 66", "6. Bern: 53", "7. Fred: 47"}
পরীক্ষায় 100-এর একটি "পারফেক্ট" স্কোর বিরল হলেও, অন্তত একজন শিক্ষার্থী সেটি অর্জন করেছে কি না, তা জানতে ভালো লাগে।
student_scores এবং student_names প্যারামিটার নিয়ে perfect_score() ফাংশনটি তৈরি করুন।
তালিকাগুলো টাস্ক ৪-এর মতোই।
ফাংশনটি পরীক্ষায় 100 পাওয়া শিক্ষার্থীর প্রথম <name>-টি (একটি স্ট্রিং হিসেবে) return করবে।
কোনো 100 স্কোর না পাওয়া গেলে, একটি খালি স্ট্রিং "" রিটার্ন করা উচিত।
perfect_score({"Nur", "Tony", "Fatima"}, {90, 80, 100});
// => "Fatima"
perfect_score({"Nur", "Tony"}, {90, 80});
// => ""
Exercism-এ সাইন আপ করুন, C++ ট্র্যাকের 19টি কনসেপ্ট100টি অনুশীলনী আর সত্যিকারের মানুষের মেন্টরিং দিয়ে শিখুন ও দক্ষ হয়ে উঠুন, সম্পূর্ণ বিনামূল্যে।