পোস্টটি পড়া হয়েছে 14,043 বার
Data Structure in Bengali

অ্যারে (Array): সবচেয়ে সহজ ডেটা স্ট্রাকচার – ২

Post updated on 12th June, 2017 at 10:02 pm

অ্যারে ডেটা স্ট্রাকচারের প্রথম পর্বে আলোচনা করা হয়েছিল এর declaration, insertion ও traversing নিয়ে। এই পর্বে আরো কয়েকটি ব্যাসিক অপারেশন সম্পর্কে আমরা জানবো।

Array Update

কোন একটা প্রোগ্রাম বা অ্যাপ্লিকেশনে অসংখ্য ডেটা নিয়ে কাজ করা লাগতে পারে। ডেটার উপর বিভিন্ন ধরণের অপারেশন বা প্রসেসিং এর প্রয়োজন হয়। যেমনঃ ফেসবুকে আমাদের প্রোফাইলের একটা নাম আছে। ফেসবুকের সার্ভারে যেই ডেটাবেজ আছে তার কোন একটা টেবিলের কোন একটা ফিল্ডে এই profile name-টা স্টোর করা আছে। আমি যখন কোন পোস্ট দেই বা কারো পোস্টে লাইক-কমেন্ট দেই তখন সবাই কিন্তু দেখতে পারে যে আমি লাইক/কমেন্ট করেছি। সেখানে আমার প্রোফাইলের নাম show করে। এই নামটা কিন্তু সার্ভারে থাকা ডেটাবেজের ঐ নির্দিষ্ট ফিল্ড থেকে নিয়ে এসে দেখানো হয়।

মনে করো পৃথিবীর সবার ফেসবুকের profile name-গুলো একটা অ্যারেতে রাখা হয়েছে। প্রতিটা ইন্ডেক্সে একটা করে নাম রাখা আছে। প্রথম ইন্ডেক্সে ধরো জাকারবার্গের নাম আছে। দ্বিতীয় ইন্ডেক্সে তোমার নাম, তৃতীয় ইন্ডেক্সে আছে আমার নাম। আমি আমার প্রোফাইল নামটা চেঞ্জ করতে চাই। এডিট অপশনে গিয়ে নামটা চেঞ্জ করে দিলেই যে কেউ আমার লাইক-কমেন্ট বা পোস্টে কিন্তু আমার আপডেট হওয়া নামটাই দেখবে। তাহলে কাজটা কিভাবে হবে? আমি এখান থেকে নামটা আপডেট করে যখন সাবমিট করব, আমাদের সেই অ্যারের তৃতীয় ইন্ডেক্সে আগের নামটা নতুন নাম দিয়ে রিপ্লেস হয়ে যাবে। তাই না? এটাই array update operation.

লক্ষ্য করো, আমরা অ্যারেকে আপডেট করেছি তার ইন্ডেক্স নাম্বার দিয়ে। এইবার বুঝার সুবিধার্তে নাম না স্টোর করে একটা ক্লাসের সকল শিক্ষার্থীর বয়স স্টোর করি। যেমনটা আগের পর্বে করেছিলাম। ধরো, age নামক অ্যারেতে ৫ জন ছাত্রের বয়স এভাবে স্টোর করা আছেঃ

.
int age[] = {7, 6, 9, 7, 5};
.

আমরা যদি চাই শূণ্যতম ইন্ডেক্সে যেই ছাত্রের বয়স আছে সেটাকে 10 দিয়ে আপডেট করতে তাহলে কোড করব এভাবেঃ

.
age[0] = 10;
.

এক্ষেত্রে অ্যারের শূণ্যতম ইন্ডেক্সের ভ্যালু ৭ আর থাকবে না। এটা রিপ্লেস হয়ে যাবে 10 দিয়ে। এভাবে ইন্ডেক্স ধরে ধরে কোন একটা অ্যারের ভ্যালু আপডেট করতে পারি।

যদি কখনো ইউজারের থেকে ইন্ডেক্সের মান আর updated value ইনপুট নিয়ে অ্যারে আপডেট করতে হয় তাহলে নিচের মত কোড করা যেতে পারেঃ

while(true) //Infinite Loop
{
    scanf("%d %d", &index, &value);
    age[index] = value;
}

মূল ব্যাপারটা এটাই। এখন যখন যেভাবে দরকার হবে সেভাবে নিজের মত করে ইমপ্লিমেন্ট করতে হবে। তবে খেয়াল রাখতে হবে যে অ্যারেতে যেই ইন্ডেক্সটি নাই সে ইন্ডেক্সে অ্যাক্সেস করছো কিনা। অর্থাৎ কোন একটা অ্যারের সাইজ ১০ হলে তার তার ইন্ডেক্সগুলো হবে ০ থেকে ৯ পর্যন্ত। তুমি যদি অ্যারের ১০ম বা ১২তম ইন্ডেক্সে কোন মান বসাতে চাও বা ১২তম ইন্ডেক্সের মান প্রিন্ট করতে চাও তাহলে প্রোগ্রাম ক্র্যাশ করবে। অনলাইন জাজ বা কনটেস্টের সময় এধরণের ঘটনায় Run Time Error নামক verdict পাবা। তাই অ্যারেতে ট্রাভার্স, ইনসার্ট, আপডেট, ডিলেট যেই অপারেশনই করো না কেন; খেয়াল রাখবে যেন এই সমস্যা তৈরি না হয়।

Deletion an Element of Array

স্টোর করা ডেটাগুলো প্রয়োজনে ডিলেট করার দরকার হতে পারে। অ্যারেতে সিকোয়েন্স অনুযায়ী ডেটা স্টোর করা থাকে। age নামক অ্যারের সাইজ ১০ হলে তার ইন্ডেক্স নাম্বার হবে ০ থেকে ৯। আমরা যদি age[6] এর ডেটাকে অ্যারে থেকে মুছে ফেলতে চাই তাহলে age[7] এর ভ্যালুকে অ্যাসাইন করতে হবে age[6] এ। age[8] এর ভ্যালুকে অ্যাসাইন করতে হবে age[7] এ। age[9] এর ভ্যালু অ্যাসাইন করতে হবে age[8] এ। তারমানে age[7] থেকে age[9] পর্যন্ত সবগুলো ভ্যালুকে আমরা ১ ঘর করে বাম দিকে সরিয়ে দিলাম। কোডটা দেখলে আরো ক্লিয়ার হবেঃ

#include<stdio.h>

int main()
{
    int arr_size = 5, index, i, j;
    int age[arr_size];

    //array input
    printf("Input 5 elements: ");
    for(i =0; i<arr_size; i++)
        scanf("%d", &age[i]);

    //input zero based index number for deletion
    printf("Input index number (0 to 4): ");
    scanf("%d", &index);

    //deletion by replacing 
    j = index;
    while(j<arr_size-1)
    {
        age[j] = age[j+1];
        j++;
    }

    arr_size = arr_size - 1;

    for(i = 0; i<arr_size; i++)
        printf("%d ", age[i]);

    return 0;
}

১৯ নাম্বার লাইনের while loop এর ভিতরে মূল রিপ্লেসিং এর কাজটা হচ্ছে। এখানে কন্ডিশন দেয়া আছে (j<arr_size-1). কারণ আমরা অ্যারের index-তম ইন্ডেক্সকে রিপ্লেস করছি (index+1)-তম ইন্ডেক্সের ভ্যালু দিয়ে। অ্যারের সাইজ যদি হয় ৫ তাহলে সর্বশেষ রিপ্লেসিং এর কাজটা হবেঃ age[3] = age[4]; কারণ 4-ই অ্যারের লাস্ট ইন্ডেক্স। লুপের ভিতরে j এর মান ১ করে বাড়ছে। while এর কন্ডিশনে (j<arr_size-1) দেয়ার মানে হচ্ছে লুপের ভিতরের কাজ চলতে থাকবে যতক্ষণ পর্যন্ত j এর মান array’র শেষ ইন্ডেক্সের চেয়ে ছোট হবে। এই প্রোগ্রামের ক্ষেত্রে শেষ ইন্ডেক্স হচ্ছে চার। তাই j এর মান ৩ হলেও লুপের ভিতরে ঢুকবে। তখন age[3] = age[4] এই কাজটা হবে। এটা করার পর j++ করা হচ্ছে। ফলে j  এর মান বেড়ে দাঁড়াবে 4. যা অ্যারের লাস্ট ইন্ডেক্স 4 এর চেয়ে ছোট নয়। তাই আর লুপের ভিতরে ঢুকবে না। বের হয়ে এসে অ্যারের সাইজ রাখা হয়েছে যেই ভ্যারিয়েবলে (arr_size) তার মান ১ কমিয়ে দিবে। এরপর FOR Loop দিয়ে প্রিন্ট করা হল আপডেটেড অ্যারেটা। এখন ৫টার বদলে চারটা এলিমেন্ট প্রিন্ট হল।

খেয়াল করে দেখো, অ্যারের শেষ ইন্ডেক্সে কিন্তু এখনো মান আছে। ম্যানুয়াল্যি age[4] প্রিন্ট করলে তোমার ইনপুট করা সর্বশেষ সংখ্যাটা প্রিন্ট হবে। arr_size ভ্যারিয়েবলের মাধ্যমে আমরা জাস্ট অ্যারের length-টা কনট্রোল করছি।

User defined function এর ধারণা থাকলে তুমি চাইলে এই deletion এর কোডটুকু দিয়ে একটা ফাংশন লিখে ফেলতে পারো। যেখানে ফাংশনের প্যারামিটার হিসেবে পাঠাবে ইন্ডেক্সের ভ্যালু। ঐ ফাংশনটা ডিলেটের কাজ করে দিবে।

Searching

যে কোন ডেটা স্ট্রাকচারের ক্ষেত্রেই ডেটা সার্চ করা অন্যতম গুরুত্বপূর্ণ অপারেশন। অ্যারেতে কোন একটা ডেটা সার্চ করার জন্য অনেকগুলো অ্যালগরিদম রয়েছে। এর মধ্যে সবচেয়ে সহজ সার্চিং অ্যালগরিদম হচ্ছে লিনিয়ার সার্চ অ্যালগরিদম। লিনিয়ার সার্চ সহ অন্যান্য সার্চিং অ্যালগরিদম সম্পর্কে জানা যাবে এখান থেকে

Sorting

অ্যারের ডেটাগুলোকে একটি নির্দিষ্ট অর্ডারে সাজানোর নামই সর্ট করা। ছোট থেকে বড় বা বড় থেকে ছোট আকারে অ্যারের ইলিমেন্টগুলোকে সাজানোর জন্য অনেকগুলো অ্যালগরিদম রয়েছে। একেকটা অ্যালগরিদমের একেকটা সুবিধা ও অসুবিধা রয়েছে। আমার ব্লগে থাকা সর্টিং অ্যালগরিদমের পোস্টগুলো একত্রে পাওয়া যাবে এখানে

8 thoughts on “অ্যারে (Array): সবচেয়ে সহজ ডেটা স্ট্রাকচার – ২

    1. স্পেসিফিক কোন পার্টে প্রবলেম হচ্ছে সেটা বললে এক্সপ্লেইন করতে সুবিধা হত

      1. apni akti “While” loop chaliachen tar por j kaj gulo korce sei khane bujte amar problem hocce. R loop tao Infinite korechen.. sei khaneo bujte problem hocce.

        1. লুপটা দিয়েছি এমনি… যেন আমার যতবার আপডেট করার দরকার ততবার করতে পারি। আপনি লুপ ছাড়াও করতে পারেন। যদি age অ্যারের কোনো একটা ইনডেক্সের ভ্যালু একবার পরিবর্তনের দরকার হয় আপনি age[index_number] = updated_value; লিখে দিবেন। যদি এক্সাক্ট ৫ বার চেঞ্জ করার দরকার হয় লুপ ঘুরিয়ে পাঁচবার আপডেট করতে পারেন। এই লুপের মধ্যে দেখাচ্ছিলাম আমি কোন ইনডেক্সের ভ্যালু কত দ্বারা আপডেট করতে চাই সেটা scanf() দিয়ে ইনপুট নেয়া হয়েছে। ইনপুট নেয়া ইনডেক্সের নাম্বার ও ভ্যালু দিয়ে অ্যারে আপডেট করা হয়েছে।

  1. আগে ( arr_size = 5) ডিক্লেয়ার পরে আবার
    age [arr_size] এর ব্যাপার টা বুঝলাম না ভাই। age [5] এইভাবে ডিক্লেয়ার করলে কি হত না? আমি নতুন শিখতেসি তাই হয়ত অনেক ব্যাকিস কিছু জিজ্ঞাসা করলাম। যদি উত্তর দিতেন তাহলে খুব উপকৃত হতাম।

    1. age[5] ডিক্লেয়ার করলেও হত। কিন্তু…

      কোডে দেখেন, বেশ কয়েক জায়গায় আমি arr_size ভ্যারিয়েবলটা ইউজ করেছি। আমি অ্যারের সাইজ প্রথমে বলে দিয়েছি 5, কিন্তু কিছুক্ষণ পর যদি অ্যারের সাইজ 50 করতে চাই তাহলে কী করব? আমার কোডে arr_size = 50 করে দিলেই কোড ঠিকঠাক কাজ করবে। কিন্তু arr_size ভ্যারিয়েব ইউজ না করে যদি সব জায়গায় প্রথম থেকে 5 ইউজ করতাম তাহলে কোডের অনেক জায়গায় 5 এর জায়গায় 50 লিখতে হত। অনেক জায়গায় চেঞ্জ করা মানে টাইপিং মিসটেক হবার আশংকা বাড়া। কোড মেইনটেইন করার সময় বাড়া। তাই hardcoded value ব্যবহার না করে variable ইউজ করা হয়েছে।

      1. আমি যদি ” j “এর জায়গাই “index” ব্যবহার করি তারপরেও তো আউটপুট একই আসছে।
        “j = index” লেখার কি কোনো সুবিধা আছে ভাইয়া?

Leave a Reply

Your email address will not be published. Required fields are marked *