Vector

STL

·

7 min read

c++ এ ভেক্টর হচ্ছে ডাইনামিক array. ডাইনামিক ভাবে আমরা এর মান ইচ্ছে মতো insert করতে পারি, remove করতে পারি এবং একসেস করতে পারি। স্ট্যাটেটিক array তে আমাদের একটা নির্দিষ্ট সাইজ নির্ধারন করে দিতে হয়, যেখানে ভেক্টরে আমাদের নির্দিষ্ট কোন সাইজ নির্ধারণ করে দিতে হয় না। এরকম আরো কিছু সুবিধা আছে যেগুলো আস্তে আস্তে জানব।

Vector declaration:

স্বাভাবিক array আমরা এভাবে declare করিঃ

int arr[10]

এবার দেখি vector declaration কিভাবে করা যায়, অনেকটা arry র মতো করেই আমরা declare করতে পারি।

vector <int> v;

structure:

vector <data_type> vector_name;

ভেক্টর ডিক্লেয়ারেশন ত জানলাম তাই না? এবার তবে দেখা যাক ভেক্টরে কিভাবে কোন এলিমেন্ট এড করা যায়। আমি উপরে যে ভেক্টর টা তৈরি করেছি সেটার নাম হচ্ছে v

v ভেক্টরে এবার ডেটা/ এলিমেন্ট এড করার প্রসেস টা দেখে নিই চলো,

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    return 0;
}

উপরের প্রোগ্রামটি খেয়াল করো, আমি ভেক্টর v তে এলিমেন্ট গুলো পুশ করবার জন্য push_back() ফাংশন টি ব্যবহার করেছি।

structure: push_back(value/element);

এবার দেখি এলিমেন্ট গুলো একসেস করা যায় কিভাবে ?

ভেক্টরের এলিমেন্ট গুলো array র মতোই আমরা ইনডেক্স এর সাহায্য নিয়ে করতে পারি। array তে যেমন করতাম না? arr[0] , arr[1], arr[2] এভাবে।

ঠিক তেমন ই ভেক্টরের এলিমেন্ট গুলোও আমরা ইন্ডেক্সিং এর মাধ্যেম একসেস করতে পারি। নিচের প্রোগ্রাম টা খেয়াল করো।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    cout << v[0] << '\n';
    cout << v[1] << '\n';
    cout << v[2] << '\n';

    return 0;
}

ইন্ডেক্সিং এর ব্যাপার টা ক্লিয়ার করার জন্য আমি একাধিক cout ব্যবহার করেছি।

আমরা কিন্তু আরও এক ভাবে ভেক্টরের ইনডেক্স গুলো প্রিন্ট করতে পারি। at() ফাংশন ব্যবহার করে। নিচের প্রোগ্রাম টা খেয়াল করো।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    cout << v.at(0) << '\n';
    cout << v.at(1) << '\n';
    cout << v.at(2) << '\n';

    return 0;
}

আবার, তুমি কিন্তু চাইলে for loop ব্যবহার করেও কাজ টা করে ফেলতে পারো।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    for (int i = 0; i < 3; i++) {
        cout << v[i] << '\n';
    }

    return 0;
}

এখানে কিন্তু প্রতিটি এলিমেন্ট একটার পরে আরেকটা এড হচ্ছে তাই না? অনেকটা এভাবে

প্রথমে element 1 যুক্ত হলো, তারপর element 2 যুক্ত হল, তারপর element 3 ।

size()

এবার আসো জেনে নিই কিভাবে ভেক্টরের সাইজ বের করে ফলব। ভেক্টরের সাইজ টা এক্সাক্টলি কত সেটা বের করবার জন্যে আমাদের size() ফাংশনের সাহায্য নিতে হবে।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    cout << v.size() << '\n';

    return 0;
}

এখানে ভেক্টরে ৫ টি এলিমেন্ট আছে তাই ভেক্টরের সাইজ ৫। অর্থাৎ তুমি যদি প্রোগ্রাম টি রান করো তাহলে কনসোলে আউটপুট 5 দেখতে পাবে।

front()

এখন তুমি যদি ভেক্টরের একদম শুরুর মান টা নিতে চাও/ একসেস করতে চাও তাহলে তুমি front() ফাংশনে ব্যবহার করে সেটি করতে পারবে।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    cout << v.front() << '\n';

    return 0;
}

back()

তুমি যদি ভেক্টরের একদম শেষ মান টার একসেস নিতে চাও তাহলে তুমি back() ফাংশন টি ব্যবহার করতে পারবে।

#include<bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    cout << v.back() << '\n';

    return 0;
}

clear()

এখন তুমি যদি চাও যে ভেক্টরের প্রতিটা এলিমেন্ট তুমি একেবারে মুছে দিবে তাহলে তুমি clear() ফাংশন টি ব্যবহার করে কাজ সেরে ফেলতে পারো।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.clear(); // vector is now empty

    cout << v.size() << '\n';

    return 0;
}

উপারে প্রোগ্রামে আমি দুটো ফাংশন ব্যবহার করেছি।

  1. clear()

  2. size()

clear() ফাংশন টি ব্যবহার করে ভেক্টরের সাইজ শূন্য করে নিয়েছি। এবং আসলেই ভেক্টরটি ক্লিয়ার হল কি না সেটি জানবার জন্য আমি size() ফাংশন টা ব্যবহার করে ভেক্টরের সাইজ জেনে নিয়েছি। তুমি প্রোগ্রাম টি রান করলেই কনসলে দেখবে 0 প্রিন্ট হয়েছে।

empty()

একটা ভেক্টরে কোন মান আছে কি না ? এ ব্যপার টা জানবার জন্য আমরা empty() ফাংশন টি ব্যবহার করে দেখতে পারি।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    cout << v.empty() << '\n';

    return 0;
}

প্রোগ্রামটি যদি রান করো তাহলে তুমি কনসোলে 1 দেখতে পাবে। 1 = true ; 0 = false;

১ প্রিন্ট হয়েছে কারণ ভেক্টর টি শুধু ডিক্লেয়ার করা হয়েছে তাতে কোন মান এসাইন করা হয় নি ।

আরেকটি উদাহরণ দেখা যাক,

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.clear();

    if (v.empty()) {
        cout << "Vector is empty\n";
    }
    else {
        cout << "Vectors size: " << v.size() << '\n';
    }

    return 0;
}

Output: Vector is empty

pop_back()

pop_back() ফাংশনটির সাহায্যে আমরা শেষ থেকে এলিমেন্ট গুলোকে ডিলেট করতে পারি।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.pop_back();

    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }
    cout << '\n';

    return 0;
}

প্রোগ্রাম টি যদি রান করো তাহলে দেখতে পারবে যে ভেক্টর থেকে 8 ডিলেট হয়ে গেছে। এভাবে তুমি যদি আবার pop_back() ফাংশনটি ব্যবহার করো তাহলে ভেক্টরের শেষ থেকে আরও একটি এলিমেন্ট ডিলিট হয়ে যাবে।

erase()

erase() ফাংশনের মাধ্যমে আমরা একটি ভেক্টরের নির্দিষ্ট ইনডেক্স গুলো ডিলিট করতে পারি। এভাবে,

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.erase(v.begin() + 0);


    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }
    cout << '\n';

    return 0;
}

প্রোগ্রামটি রান করলে দেখবে প্রথম এলিমেন্ট ডিলেট হয়ে গেছে। এখন তুমি যদি একটি নির্দিষ্ট ইনডেক্স থেকে এলিমেন্ট গুলো ডিলেট করতে চাও তাহলে,

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.erase(v.begin() + 1, v.begin() + 3);


    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }
    cout << '\n';

    return 0;
}

প্রোগ্রামটি রান করলে দেখবে যে ১ এবং ২ নং ইনডেক্স এর এলিমেন্ট ডিলিট হয়ে গেছে।

output: 9 3 8

insert()

insert() ফাংশনের সাহায্যে তুমি চাইলে একটি ভেক্টরে এলিমেন্ট এড করতে পারবে। কয়েক ভাবে করা যায় চলো একটা একটা করে দেখি।

ধরলাম তুমি ভেক্টরের ০ ইনডেক্সে কোন একটা ভ্যালু ইনসার্ট করতে চাচ্ছো তাহলে এভাবে করতে পারবে।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.insert(v.begin(), 11);


    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }

    return 0;
}

তুমি যদি ৪ নম্বর ইনডেক্স এ কোন ভ্যালু ইনসার্ট করতে চাও তাহলে এভাবে করতে পারবে।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.insert(v.begin() + 4, 4);


    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }

    return 0;
}

আবার তুমি যদি একই ভ্যালু একাধিক বার ইনসার্ট করতে চাও সেটাও করতে পারবে।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    v.insert(v.begin() + 2, 3, 4);


    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }

    return 0;
}

কঠিন লাগছে? আচ্ছা একটু সহজ করার চেষ্টা করি। নিচের চিত্র দ্যাখো।

sort()

চলো এবার দেখি ভেক্টরের এলিমেন্ট গুলোকে কিভাবে sort() করা যায়।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    cout << "Before sort:\n";
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }
    cout << '\n';

    sort(v.begin(), v.end());

    cout << "After sort:\n";

    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }

    return 0;
}

reverse()

sort() ত করলে এবার নিশ্চয়ই ভাবছ, ভেক্টরের এলিমেন্ট গুলো রিভার্স করবে কিভাবে ? প্যারা নাই চলো ক্যামনে করে দেখি।

#include <bits/stdc++.h>
using namespace std;

int main()
{
    vector<int> v;

    v.push_back(9);
    v.push_back(5);
    v.push_back(2);
    v.push_back(3);
    v.push_back(8);

    cout << "Before reverse:\n";
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }
    cout << '\n';

    reverse(v.begin(), v.end());

    cout << "After reverse:\n";

    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << ' ';
    }

    return 0;
}

ভেক্টর sort() করবার মতোই ত তাই না ?

swap()

এবার তুমি যদি দুটো ভেক্টর কে swap করতে চাও তাহলে নিচের মতো করে করে ফেলতে পারো।