অ্যাডভান্সড ডেটা স্ট্রাকচার ফোরট্রানে (Advanced Data Structures in Fortran)
ফোরট্রানে সাধারণত গাণিতিক এবং বৈজ্ঞানিক গণনার জন্য ব্যবহৃত হলেও, আধুনিক প্রোগ্রামিং চাহিদা মেটাতে অ্যাডভান্সড ডেটা স্ট্রাকচারও প্রয়োজন। ফোরট্রানে সাধারণ অ্যারে ছাড়াও বিভিন্ন ডেটা স্ট্রাকচার তৈরি করা সম্ভব, যেমন লিঙ্কড লিস্ট (Linked List), স্ট্যাক (Stack), কিউ (Queue), এবং ট্রি (Tree)। এদের মধ্যে কিছু ডেটা স্ট্রাকচার derived types এবং পয়েন্টার ব্যবহার করে তৈরি করা যায়।
১. ডেরাইভড টাইপস (Derived Types)
ডেরাইভড টাইপ ফোরট্রানে একটি কাস্টম ডেটা টাইপ তৈরি করতে ব্যবহৃত হয়, যা ব্যবহারকারী নিজেই তৈরি করতে পারেন। ডেরাইভড টাইপগুলো ব্যবহার করে অ্যাডভান্সড ডেটা স্ট্রাকচারের জন্য প্রয়োজনীয় বৈশিষ্ট্য তৈরি করা যায়।
উদাহরণ: ডেরাইভড টাইপের মাধ্যমে একটি ডেটা টাইপ তৈরি করা
type :: Person
character(len=20) :: name
integer :: age
end type Person
type(Person) :: student
student%name = "Alice"
student%age = 20এখানে, Person নামে একটি ডেরাইভড টাইপ তৈরি করা হয়েছে এবং এর মাধ্যমে student নামে একটি ভেরিয়েবল তৈরি করে name এবং age ধারণ করা হচ্ছে।
২. লিঙ্কড লিস্ট (Linked List)
ফোরট্রানে লিঙ্কড লিস্ট তৈরি করতে derived types এবং pointer ব্যবহার করা হয়। লিঙ্কড লিস্টের প্রতিটি নোডে ডেটা এবং পরবর্তী নোডের পয়েন্টার থাকে।
উদাহরণ: লিঙ্কড লিস্ট
type :: Node
integer :: data
type(Node), pointer :: next => null()
end type Node
type(Node), pointer :: head, temp
! প্রথম নোড তৈরি
allocate(head)
head%data = 10
head%next => null()
! দ্বিতীয় নোড তৈরি এবং প্রথম নোডের সাথে সংযুক্তি
allocate(temp)
temp%data = 20
temp%next => null()
head%next => tempএখানে:
Nodeনামে একটি ডেরাইভড টাইপ তৈরি করা হয়েছে, যা লিঙ্কড লিস্টের প্রতিটি নোড ধারণ করে।headএবংtempপয়েন্টার ব্যবহার করে নতুন নোড তৈরি করা হয়েছে এবং তারা পরস্পর সংযুক্ত করা হয়েছে।
৩. স্ট্যাক (Stack)
স্ট্যাক একটি লাস্ট ইন ফার্স্ট আউট (LIFO) ডেটা স্ট্রাকচার, যেখানে ডেটা পুশ এবং পপ অপারেশনের মাধ্যমে যোগ এবং সরানো যায়। ফোরট্রানে অ্যারে বা লিঙ্কড লিস্ট ব্যবহার করে স্ট্যাক তৈরি করা যায়।
উদাহরণ: অ্যারের মাধ্যমে স্ট্যাক
program stack_example
integer, parameter :: max = 5
integer :: stack(max), top = 0
contains
subroutine push(x)
integer, intent(in) :: x
if (top < max) then
top = top + 1
stack(top) = x
else
print *, "Stack Overflow"
end if
end subroutine push
subroutine pop()
if (top > 0) then
print *, "Popped:", stack(top)
top = top - 1
else
print *, "Stack Underflow"
end if
end subroutine pop
end program stack_exampleএখানে:
pushসাবরুটিন একটি নতুন মান স্ট্যাকে যোগ করে।popসাবরুটিন স্ট্যাকের উপরের মান সরিয়ে ফেলে।
৪. কিউ (Queue)
কিউ একটি ফার্স্ট ইন ফার্স্ট আউট (FIFO) ডেটা স্ট্রাকচার। ফোরট্রানে অ্যারে বা লিঙ্কড লিস্ট ব্যবহার করে কিউ তৈরি করা যায়।
উদাহরণ: অ্যারের মাধ্যমে কিউ
program queue_example
integer, parameter :: max = 5
integer :: queue(max), front = 0, rear = 0
contains
subroutine enqueue(x)
integer, intent(in) :: x
if (rear < max) then
rear = rear + 1
queue(rear) = x
else
print *, "Queue Overflow"
end if
end subroutine enqueue
subroutine dequeue()
if (front < rear) then
front = front + 1
print *, "Dequeued:", queue(front)
else
print *, "Queue Underflow"
end if
end subroutine dequeue
end program queue_exampleএখানে:
enqueueসাবরুটিন কিউতে নতুন মান যোগ করে।dequeueসাবরুটিন কিউ থেকে প্রথম মান সরিয়ে ফেলে।
৫. বাইনারি ট্রি (Binary Tree)
ফোরট্রানে পয়েন্টার এবং ডেরাইভড টাইপ ব্যবহার করে বাইনারি ট্রি তৈরি করা সম্ভব।
উদাহরণ: বাইনারি ট্রি
type :: TreeNode
integer :: data
type(TreeNode), pointer :: left => null()
type(TreeNode), pointer :: right => null()
end type TreeNode
type(TreeNode), pointer :: root, newNode
! রুট নোড তৈরি
allocate(root)
root%data = 15
root%left => null()
root%right => null()
! নতুন নোড তৈরি এবং সংযুক্তি
allocate(newNode)
newNode%data = 10
root%left => newNodeএখানে:
TreeNodeনামে একটি ডেরাইভড টাইপ তৈরি করা হয়েছে, যা বাইনারি ট্রির প্রতিটি নোড ধারণ করে।rootএবংnewNodeপয়েন্টার ব্যবহার করে ট্রিতে নোড যুক্ত করা হয়েছে।
উপসংহার
ফোরট্রানে derived types এবং pointer ব্যবহার করে লিঙ্কড লিস্ট, স্ট্যাক, কিউ এবং ট্রির মতো অ্যাডভান্সড ডেটা স্ট্রাকচার তৈরি করা সম্ভব। এই ডেটা স্ট্রাকচারগুলো গাণিতিক এবং বৈজ্ঞানিক সমস্যার সমাধানে এবং ডেটা সংরক্ষণে সহায়ক ভূমিকা পালন করে।
ফোরট্রানে Linked List এবং Dynamic Data Structures
Linked List এবং অন্যান্য Dynamic Data Structures (যেমন স্ট্যাক, কিউ, গ্রাফ ইত্যাদি) ফোরট্রানে ডায়নামিক মেমরি ব্যবস্থাপনা ব্যবহার করে ডেটা সংরক্ষণ এবং পরিচালনার অত্যন্ত গুরুত্বপূর্ণ ধারণা। এই ধরনের ডেটা স্ট্রাকচারগুলি সাধারণ অ্যারে ডেটা স্ট্রাকচারগুলির তুলনায় বেশি নমনীয় এবং মেমরি ব্যবহারে আরও দক্ষ। এর মাধ্যমে ডেটাকে একে একে সন্নিবেশিত (insert) এবং মুছে ফেলা (delete) সম্ভব হয়, যা অ্যারে ব্যবস্থায় খুবই সীমিত।
১. Linked List কী?
Linked List হলো একটি ডেটা স্ট্রাকচার, যেখানে প্রতিটি উপাদান (node) দুটি অংশে বিভক্ত: একটি ডেটা অংশ এবং একটি পয়েন্টার অংশ (যা পরবর্তী উপাদানের ঠিকানা ধারণ করে)। এটি একটি ডায়নামিক ডেটা স্ট্রাকচার কারণ এতে মেমরি বরাদ্দ এবং মুক্ত করা রানটাইমে (runtime) হতে পারে।
Linked List এর উপাদান:
- Node: প্রতিটি উপাদান (node) একটি ডেটা অংশ এবং একটি পরবর্তী node এর পয়েন্টার ধারণ করে।
- Head: লিঙ্কড লিস্টের প্রথম উপাদান।
- Tail: লিঙ্কড লিস্টের শেষ উপাদান, যার পরবর্তী node পয়েন্টার NULL থাকে।
২. ফোরট্রানে Linked List তৈরি করা
ফোরট্রানে লিঙ্কড লিস্ট তৈরি করতে ALLOCATABLE টাইপের ডেটা স্ট্রাকচার এবং পয়েন্টার ব্যবহার করা হয়। একটি সাধারিত লিঙ্কড লিস্টের উদাহরণ দেখানো হলো।
উদাহরণ: সিঙ্গল লিঙ্কড লিস্ট (Singly Linked List)
PROGRAM linked_list_example
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: head, temp, new_node
INTEGER :: value
! লিঙ্কড লিস্টের প্রথম উপাদান তৈরি করা
ALLOCATE(head)
head%data = 10
head%next_node => NULL()
! নতুন উপাদান যোগ করা
PRINT *, 'Enter a value to insert: '
READ *, value
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => NULL()
! পুরানো লিঙ্কড লিস্টের শেষে নতুন উপাদান যুক্ত করা
temp => head
DO WHILE (ASSOCIATED(temp%next_node))
temp => temp%next_node
END DO
temp%next_node => new_node
! লিঙ্কড লিস্টের উপাদান প্রিন্ট করা
PRINT *, 'Linked list elements:'
temp => head
DO WHILE (ASSOCIATED(temp))
PRINT *, temp%data
temp => temp%next_node
END DO
END PROGRAM linked_list_exampleএখানে:
- Node টাইপটি একটি data (পুরানো ডেটা) এবং next_node (পয়েন্টার) ধারণ করে।
- ALLOCATE কমান্ড দিয়ে লিঙ্কড লিস্টের জন্য মেমরি বরাদ্দ করা হয়েছে এবং ASSOCIATED ফাংশন ব্যবহার করে লিঙ্কড লিস্টের প্রতিটি উপাদান একে একে প্রিন্ট করা হয়েছে।
আউটপুট:
Enter a value to insert:
20
Linked list elements:
10
20এখানে ১০ এবং ২০ মানের দুটি উপাদান যুক্ত হয়েছে, এবং এটি লিঙ্কড লিস্টের মাধ্যমে প্রদর্শিত হচ্ছে।
৩. Dynamic Data Structures (ডায়নামিক ডেটা স্ট্রাকচার)
ডায়নামিক ডেটা স্ট্রাকচারগুলি এমন স্ট্রাকচার যা ডাটা সঞ্চয় করার জন্য রানটাইমে মেমরি বরাদ্দ ও মুক্ত করে। এ ধরনের ডেটা স্ট্রাকচারগুলি অত্যন্ত নমনীয় এবং মেমরি ব্যবস্থাপনাতে আরও দক্ষ।
ডায়নামিক ডেটা স্ট্রাকচারগুলির মধ্যে সাধারণত লিঙ্কড লিস্ট, স্ট্যাক, কিউ, গ্রাফ ইত্যাদি অন্তর্ভুক্ত হয়। এদের মধ্যে কিছু বিশেষ উদাহরণ দেওয়া হল:
১. Stack (স্ট্যাক)
স্ট্যাক একটি ডেটা স্ট্রাকচার যা Last In First Out (LIFO) প্রিন্সিপলের উপর কাজ করে। অর্থাৎ, শেষ যেটি প্রবেশ করবে, সেটিই প্রথমে বের হবে।
উদাহরণ: স্ট্যাক তৈরি করা
MODULE stack_module
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: top
CONTAINS
SUBROUTINE push(value)
INTEGER, INTENT(IN) :: value
TYPE(Node), POINTER :: new_node
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => top
top => new_node
END SUBROUTINE push
SUBROUTINE pop()
TYPE(Node), POINTER :: temp
IF (ASSOCIATED(top)) THEN
temp => top
PRINT *, 'Popped value: ', top%data
top => top%next_node
DEALLOCATE(temp)
ELSE
PRINT *, 'Stack is empty!'
END IF
END SUBROUTINE pop
END MODULE stack_module
PROGRAM stack_example
USE stack_module
INTEGER :: value
top => NULL()
CALL push(10)
CALL push(20)
CALL push(30)
CALL pop() ! 30 will be popped
CALL pop() ! 20 will be popped
CALL pop() ! 10 will be popped
CALL pop() ! Stack is empty
END PROGRAM stack_exampleএখানে:
- push সাবরুটিন স্ট্যাকের উপরে একটি নতুন উপাদান যোগ করে।
- pop সাবরুটিন স্ট্যাক থেকে উপাদান মুছে ফেলে।
২. Queue (কিউ)
কিউ একটি First In First Out (FIFO) প্রিন্সিপলে কাজ করে। অর্থাৎ, প্রথমে যে উপাদান প্রবেশ করবে, সেটিই প্রথমে বের হবে।
উদাহরণ: কিউ তৈরি করা
MODULE queue_module
TYPE Node
INTEGER :: data
POINTER :: next_node => NULL()
END TYPE Node
TYPE(Node), POINTER :: front, rear
CONTAINS
SUBROUTINE enqueue(value)
INTEGER, INTENT(IN) :: value
TYPE(Node), POINTER :: new_node
ALLOCATE(new_node)
new_node%data = value
new_node%next_node => NULL()
IF (.NOT. ASSOCIATED(front)) THEN
front => new_node
rear => new_node
ELSE
rear%next_node => new_node
rear => new_node
END IF
END SUBROUTINE enqueue
SUBROUTINE dequeue()
TYPE(Node), POINTER :: temp
IF (ASSOCIATED(front)) THEN
temp => front
PRINT *, 'Dequeued value: ', front%data
front => front%next_node
DEALLOCATE(temp)
ELSE
PRINT *, 'Queue is empty!'
END IF
END SUBROUTINE dequeue
END MODULE queue_module
PROGRAM queue_example
USE queue_module
INTEGER :: value
front => NULL()
rear => NULL()
CALL enqueue(10)
CALL enqueue(20)
CALL enqueue(30)
CALL dequeue() ! 10 will be dequeued
CALL dequeue() ! 20 will be dequeued
CALL dequeue() ! 30 will be dequeued
CALL dequeue() ! Queue is empty
END PROGRAM queue_exampleএখানে:
- enqueue সাবরুটিন কিউতে একটি নতুন উপাদান যোগ করে।
- dequeue সাবরুটিন কিউ থেকে একটি উপাদান মুছে ফেলে।
উপসংহার
ফোরট্রানে Linked List এবং Dynamic Data Structures ব্যবহার করে ডেটা সংরক্ষণ ও পরিচালনার দক্ষতা বাড়ানো যায়। লিঙ্কড লিস্ট, স্ট্যাক এবং কিউ এই ধরনের ডায়নামিক ডেটা স্ট্রাকচারগুলির মধ্যে জনপ্রিয়। এগুলি মেমরি ব্যবস্থাপনায় আরও নমনীয় এবং কোডের কার্যকারিতা উন্নত করতে সাহায্য করে, বিশেষ করে যখন আপনি জানেন না কতটুকু মেমরি প্রয়োজন হবে বা ডেটা সাইজ পরিবর্তনশীল।
ফোরট্রানে Derived Types এর মাধ্যমে কাস্টম ডেটা স্ট্রাকচার তৈরি
ফোরট্রানে Derived Types (বা User-defined Types) ব্যবহার করে আপনি কাস্টম ডেটা স্ট্রাকচার তৈরি করতে পারেন। এটি ফোরট্রানের একটি শক্তিশালী বৈশিষ্ট্য যা আপনাকে বিভিন্ন ডেটার ধরন (যেমন, ইন্টিজার, রিয়েল, ক্যারেক্টার ইত্যাদি) একত্রিত করে একটি নতুন টাইপ তৈরি করতে সাহায্য করে।
Derived Type দিয়ে আপনি একটি নতুন ডেটা টাইপ তৈরি করতে পারেন, যা বিভিন্ন প্রপার্টি বা ভ্যারিয়েবল ধারণ করতে পারে। এটি মূলত Struct এর মতো কাজ করে, যা C প্রোগ্রামিং ভাষায় ব্যবহৃত হয়।
১. Derived Type তৈরি করার সাধারণ গঠন
type :: type_name
! সদস্য (members) ঘোষণা
type1 :: member1
type2 :: member2
...
end type type_nametype_name: আপনার তৈরি করা ডেটা টাইপের নাম।type1,type2, ...: এই ডেটা টাইপের সদস্য ভ্যারিয়েবল বা উপাদানগুলির ডেটা টাইপ।
২. Derived Type এর উদাহরণ
ধরা যাক, আপনি একটি Person নামক ডেটা টাইপ তৈরি করতে চান, যা মানুষের নাম, বয়স এবং উচ্চতা ধারণ করবে।
program derived_type_example
implicit none
! Derived Type ডিক্লারেশন
type :: Person
character(len=30) :: name
integer :: age
real :: height
end type Person
! ভেরিয়েবল ঘোষণা
type(Person) :: p1, p2
! সদস্য ভ্যারিয়েবল মান সেট করা
p1%name = 'John Doe'
p1%age = 30
p1%height = 5.9
p2%name = 'Jane Smith'
p2%age = 25
p2%height = 5.7
! মান প্রিন্ট করা
print *, 'Person 1: ', p1%name, ', Age: ', p1%age, ', Height: ', p1%height
print *, 'Person 2: ', p2%name, ', Age: ', p2%age, ', Height: ', p2%height
end program derived_type_exampleএখানে:
type Personদিয়ে আমরা একটি কাস্টম টাইপ তৈরি করেছি, যার মধ্যেname,age, এবংheightসদস্য আছে।p1%name,p1%age,p1%heightসদস্য অ্যাক্সেস করার জন্য%সিম্বল ব্যবহার করা হয়েছে।আউটপুট হবে:
Person 1: John Doe , Age: 30 , Height: 5.9 Person 2: Jane Smith , Age: 25 , Height: 5.7
৩. Derived Type এ ফাংশন এবং সাবরুটিন ব্যবহার
ফোরট্রানে আপনি Derived Type এর মধ্যে function বা subroutine অন্তর্ভুক্ত করতে পারেন। এর মাধ্যমে আপনি ডেটা টাইপের উপর নির্দিষ্ট কাজ বা অপারেশন করতে পারেন।
ফাংশন ব্যবহার করা:
program derived_type_with_function
implicit none
! Derived Type ডিক্লারেশন
type :: Rectangle
real :: length
real :: width
contains
procedure :: area
end type Rectangle
! Derived Type এর ফাংশন
contains
function area(this)
real :: area
class(Rectangle), intent(in) :: this
area = this%length * this%width
end function area
! ভেরিয়েবল ঘোষণা
type(Rectangle) :: rect
! সদস্য ভ্যারিয়েবল মান সেট করা
rect%length = 5.0
rect%width = 3.0
! ফাংশন কল
print *, 'Area of rectangle: ', rect%area()
end program derived_type_with_functionএখানে:
Rectangleটাইপের মধ্যেlengthএবংwidthসদস্য আছে এবংareaনামক একটি ফাংশন রয়েছে।rect%area()ফাংশন কল করে আমরা আয়তক্ষেত্রের এলাকা বের করছি।
আউটপুট হবে:
Area of rectangle: 15.0৪. Derived Type এর মধ্যে Array বা অন্যান্য Derived Type ব্যবহার করা
ফোরট্রানে Derived Type এর মধ্যে অ্যারে বা অন্য Derived Type অন্তর্ভুক্ত করা সম্ভব। এটি আপনাকে আরও জটিল ডেটা স্ট্রাকচার তৈরি করতে সাহায্য করে।
Derived Type এর মধ্যে Array ব্যবহার করা:
program derived_type_with_array
implicit none
! Derived Type ডিক্লারেশন
type :: Student
character(len=30) :: name
integer :: scores(5)
end type Student
! ভেরিয়েবল ঘোষণা
type(Student) :: student1
! সদস্য ভ্যারিয়েবল মান সেট করা
student1%name = 'John Doe'
student1%scores = [85, 90, 78, 92, 88]
! ছাত্রের নাম এবং স্কোর প্রিন্ট করা
print *, 'Student: ', student1%name
print *, 'Scores: ', student1%scores
end program derived_type_with_arrayএখানে:
scores(5)অ্যারের মধ্যে ৫টি মান রয়েছে যাstudent1এর জন্য সেট করা হয়েছে।আউটপুট হবে:
Student: John Doe Scores: 85 90 78 92 88
৫. Derived Type এর সুবিধা
- কাস্টম ডেটা স্ট্রাকচার: আপনি আপনার প্রয়োজন অনুযায়ী কাস্টম ডেটা টাইপ তৈরি করতে পারেন।
- মডুলার এবং পরিষ্কার কোড: ডেটা টাইপের মধ্যে সম্পর্কিত তথ্য এবং ফাংশন একত্রিত করতে পারে, যা কোডের রক্ষণাবেক্ষণ সহজ করে তোলে।
- কোড পুনঃব্যবহারযোগ্যতা: একবার ডেটা টাইপ তৈরি করার পরে, এটি পুনরায় ব্যবহার করা যায় অন্য অংশে।
- ডেটা নিরাপত্তা: আপনি ডেটা এবং তার কার্যক্রমকে একত্রিত করে কোডের নিরাপত্তা বাড়াতে পারেন, যেমন, তথ্য অপ্রয়োজনীয়ভাবে অ্যাক্সেস বা পরিবর্তন করা থেকে বিরত থাকা।
উপসংহার
ফোরট্রানে Derived Types ব্যবহারের মাধ্যমে আপনি কাস্টম ডেটা স্ট্রাকচার তৈরি করতে পারেন, যা কোডকে আরও মডুলার এবং কার্যকরী করে তোলে। এটি ডেটা এবং কার্যকলাপকে একত্রিত করে আরও পরিষ্কার এবং রক্ষণাবেক্ষণযোগ্য কোড তৈরি করতে সহায়ক। Array বা অন্য Derived Type অন্তর্ভুক্ত করে আপনি আরও জটিল স্ট্রাকচার তৈরি করতে পারেন এবং ফাংশন ও সাবরুটিনের মাধ্যমে এর কার্যক্রম পরিচালনা করতে পারেন।
ফোরট্রানে Allocatable Components এর ব্যবহার
ফোরট্রানে Allocatable কিওয়ার্ডটি ডাইনামিক মেমরি বরাদ্দের জন্য ব্যবহৃত হয়। যখন আমরা একটি ডাইনামিক অ্যারে বা অন্যান্য ডাটা কাঠামো তৈরি করতে চাই, যার আকার রানটাইমে পরিবর্তিত হতে পারে, তখন Allocatable কম্পোনেন্ট ব্যবহৃত হয়। Allocatable কম্পোনেন্টগুলো খুবই গুরুত্বপূর্ণ কারণ এগুলির আকার কোড চলাকালীন সময় নির্ধারণ করা যায় এবং পরে প্রয়োজনীয়তা অনুযায়ী মেমরি বরাদ্দ বা মুক্ত করা যায়।
ফোরট্রানে allocatable components ব্যবহার করা হয় মেমরি ব্যবস্থাপনা উন্নত করতে, বিশেষ করে যখন অ্যারের আকার পরিবর্তনশীল এবং বড় আকারের ডেটাসেটের সাথে কাজ করা হয়।
১. Allocatable Components এর সাধারণ ব্যবহার
ফোরট্রানে allocatable কম্পোনেন্ট একটি মডিউল বা প্রোগ্রামে একটি ডাইনামিক অ্যারে, মেটাডেটা, বা অন্যান্য ডেটা কাঠামো তৈরি করতে ব্যবহৃত হয়। এটি কোডের মেমরি ব্যবস্থাপনা সঠিকভাবে করতে সাহায্য করে এবং খুব বড় ডেটাসেটের সাথে কাজ করার সময় ডাইনামিক মেমরি বরাদ্দের সুবিধা প্রদান করে।
Allocatable অ্যারে ব্যবহারের উদাহরণ:
program allocatable_example
integer, allocatable :: arr(:)
integer :: n
! আকার ডাইনামিকভাবে নির্ধারণ করা
print *, "Enter the size of the array: "
read *, n
! অ্যারে বরাদ্দ করা
allocate(arr(n))
! অ্যারে ইনিশিয়ালাইজ করা
arr = 5
! অ্যারে আউটপুট দেখানো
print *, "Array contents: ", arr
! অ্যারে মুক্ত করা
deallocate(arr)
print *, "Array deallocated successfully."
end program allocatable_exampleব্যাখ্যা:
- এখানে, allocatable অ্যারে arr ডাইনামিকভাবে বরাদ্দ করা হয়েছে। ব্যবহারকারীর ইনপুট অনুযায়ী অ্যারের আকার নির্ধারিত হয়।
- অ্যারে বরাদ্দ করার পর, এটি ইনিশিয়ালাইজ করা হয়েছে এবং তারপর প্রিন্ট করা হয়েছে।
- শেষে, deallocate কমান্ড ব্যবহার করে মেমরি মুক্ত করা হয়েছে।
আউটপুট হবে:
Enter the size of the array:
5
Array contents: 5 5 5 5 5
Array deallocated successfully.২. Allocatable Components in Modules (মডিউলে Allocatable কম্পোনেন্ট)
ফোরট্রানে মডিউলগুলিতে allocatable components ব্যবহার করা সাধারণ। মডিউলগুলি প্রোগ্রামের ভিন্ন অংশে ডাইনামিক অ্যারের সাথে কাজ করতে দেয় এবং মডিউলের মাধ্যমে সেই অ্যারে একাধিক অংশে ব্যবহার করা যায়।
উদাহরণ: মডিউলে allocatable কম্পোনেন্ট ব্যবহার
module dynamic_array
implicit none
integer, allocatable :: arr(:)
contains
! অ্যারে বরাদ্দের জন্য সাবরুটিন
subroutine allocate_array(size)
integer :: size
allocate(arr(size))
arr = 0
end subroutine allocate_array
! অ্যারের মান প্রিন্ট করার জন্য সাবরুটিন
subroutine print_array
print *, "Array contents: ", arr
end subroutine print_array
end module dynamic_array
program main
use dynamic_array
integer :: n
print *, "Enter size for the array: "
read *, n
! অ্যারে বরাদ্দ করা
call allocate_array(n)
! অ্যারে প্রিন্ট করা
call print_array
! অ্যারে মুক্ত করা
deallocate(arr)
print *, "Array deallocated successfully."
end program mainব্যাখ্যা:
- dynamic_array মডিউলে একটি allocatable অ্যারে arr তৈরি করা হয়েছে।
- allocate_array সাবরুটিনটি অ্যারের সাইজ নেয় এবং allocate দিয়ে মেমরি বরাদ্দ করে, তারপর সেটিকে শূন্য দ্বারা ইনিশিয়ালাইজ করা হয়।
- print_array সাবরুটিন অ্যারের কনটেন্ট প্রিন্ট করে।
- deallocate কমান্ড ব্যবহারের মাধ্যমে মেমরি মুক্ত করা হয়েছে।
৩. Allocatable Components এবং টাইপ
Allocatable কম্পোনেন্ট শুধুমাত্র অ্যারে নয়, অন্যান্য ডাটা টাইপের জন্যও ব্যবহার করা যেতে পারে। যেমন allocatable পয়েন্টার বা স্ট্রাকচার, যেগুলি ডাইনামিকভাবে আকার পরিবর্তন করতে পারে।
উদাহরণ: Allocatable Structure এর ব্যবহার
module dynamic_structure
implicit none
type :: person
character(len=100) :: name
integer :: age
end type person
type(person), allocatable :: people(:)
contains
! স্ট্রাকচার অ্যারে বরাদ্দ করার জন্য সাবরুটিন
subroutine allocate_people(n)
integer :: n
allocate(people(n))
end subroutine allocate_people
end module dynamic_structure
program main
use dynamic_structure
integer :: n
print *, "Enter the number of people: "
read *, n
! স্ট্রাকচার অ্যারে বরাদ্দ করা
call allocate_people(n)
! ইনপুট গ্রহণ এবং প্রিন্ট করা
do i = 1, n
print *, "Enter name of person ", i, ": "
read *, people(i)%name
print *, "Enter age of person ", i, ": "
read *, people(i)%age
end do
! স্ট্রাকচার অ্যারের কনটেন্ট প্রিন্ট করা
print *, "People data:"
do i = 1, n
print *, people(i)%name, people(i)%age
end do
! অ্যারে মুক্ত করা
deallocate(people)
print *, "People data deallocated successfully."
end program mainব্যাখ্যা:
- person নামক একটি টাইপ ডিফাইন করা হয়েছে যা মানুষের নাম এবং বয়স ধারণ করবে।
- people নামক একটি allocatable স্ট্রাকচার অ্যারে ডাইনামিকভাবে বরাদ্দ করা হয়েছে এবং এর উপাদানগুলির জন্য ইনপুট নেওয়া হয়েছে।
- শেষের দিকে deallocate ব্যবহার করে মেমরি মুক্ত করা হয়েছে।
উপসংহার
Allocatable components ফোরট্রানে ডাইনামিক মেমরি ব্যবস্থাপনার একটি শক্তিশালী উপায়। ALLOCATE এবং DEALLOCATE ব্যবহার করে আপনি মেমরি বরাদ্দ এবং মুক্ত করতে পারেন, যা ডেটা কাঠামো এবং অ্যারের আকার পরিবর্তনশীল হওয়া পরিস্থিতিতে খুবই উপকারী। মডিউল, স্ট্রাকচার বা অ্যারে এর মধ্যে allocatable ব্যবহার করলে আপনার কোড মডুলার, পুনঃব্যবহারযোগ্য এবং সহজে রক্ষণাবেক্ষণযোগ্য হয়ে ওঠে।
কমপ্লেক্স ডেটা স্ট্রাকচার এবং তাদের ব্যবহার (Complex Data Structures and Their Usage)
কমপ্লেক্স ডেটা স্ট্রাকচার হলো এমন ডেটা স্ট্রাকচার যেগুলি একাধিক প্রাথমিক ডেটা টাইপ (যেমন ইন্টিজার, রিয়েল, চ্যারেক্টার) বা অন্যান্য ডেটা স্ট্রাকচার ধারণ করতে পারে। এই ডেটা স্ট্রাকচারগুলি আরও উন্নত এবং বৃহত্তর সমস্যা সমাধানে ব্যবহার হয়, যেমন টেবিল, গ্রাফ, এবং হায়ারার্কিক্যাল ডেটা মডেল। ফোরট্রানে এই ধরনের ডেটা স্ট্রাকচারগুলি ব্যবহারের জন্য কিছু শক্তিশালী কৌশল রয়েছে।
১. অ্যারে (Arrays)
অ্যারে হলো এক ধরনের ডেটা স্ট্রাকচার যা একই ধরনের ডেটা একাধিক উপাদান ধারণ করতে পারে। এটি সাধারণত সিকোয়েনশিয়াল ডেটা সংরক্ষণের জন্য ব্যবহৃত হয় এবং এটি এক বা একাধিক মাত্রায় হতে পারে (এক-মাত্রিক, দুই-মাত্রিক, বা বহু-মাত্রিক অ্যারে)।
উদাহরণ:
integer, dimension(5) :: arr
arr = (/1, 2, 3, 4, 5/)এখানে, arr হলো একটি এক-মাত্রিক অ্যারে যা ৫টি পূর্ণসংখ্যা ধারণ করে।
ব্যবহার:
- গণনা সম্পর্কিত সমস্যা যেমন ম্যাট্রিক্স অপারেশন বা গ্রিড ভিত্তিক গণনা।
- সিমুলেশন মডেল এবং ডেটা সংগ্রহের জন্য ব্যবহৃত হয়।
২. স্ট্রাকচার (Structures)
ফোরট্রানে স্ট্রাকচার এমন একটি ডেটা টাইপ যা একাধিক ভিন্ন ভিন্ন ডেটা টাইপকে একটি ইউনিটে সংযুক্ত করে। স্ট্রাকচারগুলি ব্যবহারকারীর নিজস্ব কাস্টম ডেটা টাইপ তৈরি করতে সহায়ক, যেখানে বিভিন্ন ধরনের ডেটা একত্রিত হতে পারে।
উদাহরণ:
type Person
character(len=20) :: name
integer :: age
end type Person
type(Person) :: individual
individual%name = "John"
individual%age = 25এখানে, Person একটি স্ট্রাকচার যা name এবং age ধারণ করে।
ব্যবহার:
- জটিল ডেটা সংগঠন বা বৈজ্ঞানিক/প্রযুক্তিগত অ্যাপ্লিকেশন যেখানে একাধিক ভিন্ন ডেটা টাইপ সংযুক্ত করা প্রয়োজন।
৩. লিঙ্কড লিস্ট (Linked Lists)
লিঙ্কড লিস্ট হলো এমন একটি ডেটা স্ট্রাকচার যা উপাদানগুলির একটি সিরিজ বা চেইন ধারণ করে। প্রতিটি উপাদান (নোড) পরবর্তী উপাদানের (নোডের) ঠিকানা বা পয়েন্টার ধারণ করে, যা একে অপরের সাথে যুক্ত থাকে।
উদাহরণ:
ফোরট্রানে লিঙ্কড লিস্ট সাধারণত পয়েন্টারের মাধ্যমে তৈরি হয়।
type Node
integer :: data
type(Node), pointer :: next
end type Node
type(Node), pointer :: head, temp
allocate(head)
head%data = 10
allocate(temp)
temp%data = 20
head%next => tempএখানে, Node একটি লিঙ্কড লিস্টের নোড, এবং head এবং temp পয়েন্টার দ্বারা একে অপরকে সংযুক্ত করা হয়েছে।
ব্যবহার:
- ডাইনামিক ডেটা পরিচালনা, যেমন ডেটা ইনসার্ট বা ডিলিট করা।
- স্ট্যাক, কিউ, এবং গ্রাফ ডেটা স্ট্রাকচার তৈরি করতে ব্যবহৃত হয়।
৪. গ্রাফ (Graphs)
গ্রাফ হলো একটি ডেটা স্ট্রাকচার যেখানে নোড বা ভেরটিসেস এবং তাদের মধ্যে সংযোগ বা এজ (edge) থাকে। এটি কম্পিউটার সায়েন্সে সম্পর্কিত ডেটার মডেলিং এর জন্য ব্যবহৃত হয়।
উদাহরণ:
ফোরট্রানে গ্রাফের জন্য অ্যারে বা লিঙ্কড লিস্ট ব্যবহার করা হতে পারে।
type Node
integer :: data
type(Node), pointer :: next
end type Node
type(Node), pointer :: graph(5)
allocate(graph(5))
graph(1)%data = 1
graph(2)%data = 2এখানে, graph হলো একটি ৫টি নোড ধারণকারী গ্রাফ। প্রতি নোডের মধ্যে data এবং পরবর্তী নোডের পয়েন্টার থাকে।
ব্যবহার:
- সড়ক, নেটওয়ার্ক বা সোশ্যাল মিডিয়া সম্পর্কিত সমস্যা মডেল করতে ব্যবহৃত হয়।
- কমিউনিকেশন নেটওয়ার্ক, ফ্লো চার্ট এবং সার্কিট ডিজাইন মডেলিং।
৫. হ্যাশ টেবিল (Hash Tables)
হ্যাশ টেবিল একটি ডেটা স্ট্রাকচার যা ডেটা অ্যাক্সেস বা অনুসন্ধানকে দ্রুত করার জন্য ব্যবহৃত হয়। এটি একটি হ্যাশ ফাংশন ব্যবহার করে ডেটাকে একটি নির্দিষ্ট ইনডেক্স বা কী (key) দ্বারা মেমরিতে সংরক্ষণ করে।
উদাহরণ:
integer, dimension(10) :: hash_table
integer :: key, index
! Key থেকে ইনডেক্স বের করা
key = 25
index = mod(key, 10)
hash_table(index) = keyএখানে, hash_table হলো একটি হ্যাশ টেবিল যা key মান অনুযায়ী ইনডেক্স নির্ধারণ করে ডেটা সংরক্ষণ করে।
ব্যবহার:
- দ্রুত অনুসন্ধান এবং ডেটা প্রবাহ ব্যবস্থাপনা।
- স্টোরেজ ব্যবস্থাপনা, ক্যাশিং, এবং ডেটা অনুসন্ধানে ব্যবহৃত হয়।
৬. ডিকশনারি (Dictionaries)
ডিকশনারি একটি কাস্টম ডেটা স্ট্রাকচার যেখানে একটি কী-ভ্যালু পেয়ার থাকে, যেখানে প্রতিটি কী একটি ভ্যালুকে প্রতিনিধিত্ব করে। এটি ডেটাকে সহজে সংরক্ষণ এবং খুঁজে পাওয়ার জন্য ব্যবহৃত হয়।
উদাহরণ:
ফোরট্রানে ডিকশনারি কনসেপ্ট বাস্তবায়ন করা হলেও, এটি সাধারণত অ্যারে বা মডিউলের মাধ্যমে করা হয়। উদাহরণস্বরূপ, একটি অ্যারের মধ্যে কী এবং ভ্যালু সংরক্ষণ:
type Dictionary
character(len=20) :: key
integer :: value
end type Dictionary
type(Dictionary), dimension(10) :: dict
dict(1)%key = "apple"
dict(1)%value = 5এখানে, dict হলো একটি ডিকশনারি যেখানে key হলো apple এবং value হলো ৫।
ব্যবহার:
- কাস্টম ডেটা সংরক্ষণ এবং দ্রুত খোঁজা।
- অটোকমপ্লিট, সিলেকশন ডেটা, বা অর্গানাইজড ডেটা স্টোরেজ ব্যবস্থাপনায় ব্যবহৃত হয়।
উপসংহার
কমপ্লেক্স ডেটা স্ট্রাকচারগুলি যেমন অ্যারে, স্ট্রাকচার, লিঙ্কড লিস্ট, গ্রাফ, হ্যাশ টেবিল এবং ডিকশনারি বিভিন্ন ক্ষেত্রে ব্যবহৃত হয় এবং এগুলির মাধ্যমে উন্নত প্রোগ্রামিং এবং ডেটা ব্যবস্থাপনা করা সম্ভব। ফোরট্রানে এই ধরনের ডেটা স্ট্রাকচার ব্যবহার করে ডাইনামিক ডেটা পরিচালনা এবং মেমরি ব্যবস্থাপনা সহজ ও দক্ষভাবে করা যেতে পারে।
Read more