What Are ADTs? (ADT ဆိုတာ ဘာလဲ)
B4.1.1 (HL): Explain the properties and purpose of ADTs in programming.
မြန်မာလို: programming မှာ ADT (abstract data type၊ operation တွေနဲ့ သတ်မှတ်တဲ့ ဒေတာ အမျိုးအစား) တွေရဲ့ ဂုဏ်သတ္တိတွေနဲ့ ရည်ရွယ်ချက်ကို ရှင်းပြနိုင်ရပါမယ်။
ဒီစာမျက်နှာက HL အတွက်ပဲ ဖြစ်ပါတယ်။ SL (Standard Level) နဲ့ HL (Higher Level) ဆိုတာ IB Computer Science (နိုင်ငံတကာ ကျောင်းတွေမှာ သင်တဲ့ ကွန်ပျူတာသိပ္ပံ သင်ရိုး) သင်တန်းရဲ့ အဆင့်နှစ်ဆင့်ဖြစ်ပြီး HL အပိုင်းတွေက ပိုနက်နက်ရှိုင်းရှိုင်း လေ့လာရတဲ့ အပိုင်းတွေပါ။
အဓိက အယူအဆများ
Abstract Data Type (operation တွေနဲ့ သတ်မှတ်တဲ့ ဒေတာ အမျိုးအစား၊ အတိုကောက် ADT) ဆိုတာ ဒေတာပေါ်မှာ ဘာ operation (ဒေတာပေါ်မှာ လုပ်တဲ့ လုပ်ဆောင်ချက်) တွေ လုပ်လို့ရလဲ ဆိုတာကို ဖော်ပြပေးတဲ့ သီအိုရီ model တစ်ခုပါ။ အဲဒီ operation တွေကို အတွင်းမှာ ဘယ်လို လုပ်ဆောင်လဲ ဆိုတာကိုတော့ မသတ်မှတ်ပါဘူး။
အလိုအလျောက် ပစ္စည်းရောင်းစက် (vending machine) တစ်လုံးလို့ မြင်ကြည့်ပါ: ပိုက်ဆံ ထည့်၊ ခလုတ် နှိပ်ရင် ပစ္စည်း တစ်ခု ထွက်လာတယ်ဆိုတာ သိပါတယ်။ စက်ထဲက ယန္တရားက ပစ္စည်းကို ဘယ်လို ရွေးပြီး ထုတ်ပေးလဲ ဆိုတာ သိဖို့ မလိုပါဘူး။ Interface (အသုံးပြုသူ ထိတွေ့ သုံးရတဲ့ အပိုင်း၊ ဒီဥပမာမှာ ခလုတ်တွေနဲ့ အကြွေစေ့ ထည့်ပေါက်) က implementation (နောက်ကွယ်မှာ တကယ် အလုပ်လုပ်ပေးတဲ့ အပိုင်း၊ ဒီဥပမာမှာ မော်တာတွေနဲ့ ပစ္စည်း ရွှေ့ပေးတဲ့ ခါးပတ်တွေ) နဲ့ သီးခြားစီ ဖြစ်ပါတယ်။
ADT တစ်ခုရဲ့ အဓိက ဂုဏ်သတ္တိများ:
- Interface: data type (ဒေတာ အမျိုးအစား) က သုံးခွင့်ပေးထားတဲ့ operation တွေကို ရှင်းရှင်းလင်းလင်း သတ်မှတ်ထားတဲ့ အစု (ဥပမာ
add,remove,search) - Encapsulation (ဒေတာနဲ့ method ကို တစ်စုတည်း ထုပ်ပိုးခြင်း): အတွင်းမှာ သိမ်းထားတဲ့ ဒေတာ (internal state) ကို ဖုံးထားပါတယ်။ အသုံးပြုသူတွေက သတ်မှတ်ထားတဲ့ operation တွေကနေ တစ်ဆင့်ပဲ သုံးနိုင်ပါတယ်
- Modularity (အပိုင်းငယ်တွေ ခွဲထားလို့ တစ်ပိုင်းချင်း လဲလို့ရခြင်း): ADT ကို သုံးတဲ့ code ကို မပြောင်းဘဲ implementation ကို အစားထိုး လဲလို့ ရပါတယ်
ဘာကြောင့် အရေးကြီးသလဲ: list လို ADT တစ်ခုတည်းကို array (အရွယ်အစား ပုံသေ၊ အမျိုးအစားတူ ဒေတာစု) နဲ့လည်း implement လုပ်လို့ရသလို linked list (node တွေ ချိတ်ဆက်ထားတဲ့ list) နဲ့လည်း implement လုပ်လို့ ရပါတယ်။ List ကို သူ့ operation တွေကနေ တစ်ဆင့်ပဲ သုံးတဲ့ code က implementation ပြောင်းသွားတဲ့အခါ ပြောင်းဖို့ မလိုပါဘူး။ ဒါက abstraction (မလိုတဲ့ အသေးစိတ်ကို ဖယ်ပြီး အဓိကကိုပဲ ကြည့်ခြင်း) ရဲ့ အကျိုးကျေးဇူးပါ: code က list ဘာလုပ်လဲ ဆိုတာပေါ်မှာပဲ မူတည်ပြီး ဒေတာကို ဘယ်လို သိမ်းလဲ ဆိုတာပေါ်မှာ မမူတည်ပါဘူး။
အဓိက Operation လေးမျိုး
ADT အများစုမှာ အောက်က အခြေခံ operation တွေထဲက တချို့ကို ပေါင်းစပ်ပြီး ပေးထားပါတယ်:
| Operation | ဘာလုပ်လဲ | ဥပမာ |
|---|---|---|
| Insertion | element (အစုထဲက အချက်) အသစ် တစ်ခု ထည့်ပါတယ် | ကျောင်းသား တစ်ယောက်ကို အတန်းစာရင်းထဲ ထည့်ခြင်း |
| Deletion | ရှိပြီးသား element တစ်ခုကို ဖယ်ထုတ်ပါတယ် | ပယ်ဖျက်လိုက်တဲ့ မှာယူမှု (order) တစ်ခုကို ဖယ်ထုတ်ခြင်း |
| Traversal | element တိုင်းကို အစဉ်လိုက် တစ်ခုချင်း သွားကြည့်ပါတယ် | playlist (သီချင်းစာရင်း) ထဲက item (အချက်) အားလုံးကို print ထုတ်ခြင်း |
| Search | သတ်မှတ်ထားတဲ့ element တစ်ခုကို ရှာပါတယ် | စာအုပ်အမည်နဲ့ စာအုပ် တစ်အုပ်ကို ရှာခြင်း |
Static Data Structure (အရွယ်အစား ပုံသေ data structure) နဲ့ Dynamic Data Structure (ကြီးလာ၊ သေးသွားနိုင်တဲ့ data structure)
| ဂုဏ်သတ္တိ | Static (ဥပမာ array) | Dynamic (ဥပမာ linked list) |
|---|---|---|
| အရွယ်အစား | ဖန်တီးပြီးတာနဲ့ ပုံသေ ဖြစ်သွားပါတယ် (အရှည်ကို program run နေစဉ်မှာ ရွေးလို့ရပေမယ့် အဲဒီနောက် ဘယ်တော့မှ မပြောင်းပါဘူး) | Program run နေစဉ် ကြီးလာ၊ သေးသွားနိုင်ပါတယ် |
| Memory | Contiguous block (memory ထဲမှာ ဆက်တိုက် ကပ်လျက် ရှိတဲ့ အပိုင်း) တစ်ခု၊ နေရာ အလဟဿ ဖြစ်နိုင်ပါတယ် | Node (ဒေတာ သိမ်းထားတဲ့ အကွက်) တစ်ခုချင်းအတွက် လိုမှသာ ခွဲပေးပါတယ် |
| Insertion/Deletion | နှေးပါတယ်: element တွေကို နေရာ ရွှေ့ပေးရပါတယ် | မြန်ပါတယ်၊ reference (object ရှိရာ memory နေရာကို ညွှန်းတဲ့ တန်ဖိုး) တွေကိုပဲ ပြင်ရပါတယ် |
| Index (နေရာအမှတ်) နဲ့ ယူသုံးခြင်း | မြန်ပါတယ်: တိုက်ရိုက် O(1) | နှေးပါတယ်: traverse (element တိုင်းကို အစဉ်တကျ သွားကြည့်) လုပ်ရပါတယ် O(n) |
Array လို static data structure က contiguous memory ပုံသေ အပိုင်း တစ်ခုကို ခွဲယူထားပါတယ်။ အရွယ်အစား 100 ရှိတဲ့ array တစ်ခု ဖန်တီးပြီး item 10 ခုပဲ သိမ်းရင် နေရာ 90 ခု အလဟဿ ဖြစ်ပါတယ်။ Item 101 ခု သိမ်းဖို့ လိုရင်တော့ သိမ်းလို့ မရပါဘူး။
Dynamic data structure ကတော့ လိုတဲ့အချိန်မှ memory ကို ခွဲယူပါတယ်။ Element တစ်ခုစီ (node လို့ ခေါ်ပါတယ်) ကို နေရာလွတ် ရှိတဲ့ ဘယ်နေရာမှာမဆို သိမ်းပြီး node တွေကို reference တွေ (pointer လို့လည်း ခေါ်ပါတယ်) နဲ့ ချိတ်ဆက်ထားပါတယ်။ Program run နေစဉ်မှာ structure က ကြီးလာ၊ သေးသွားနိုင်ပါတယ်။
ဒီအပိုင်းမှာ တည်ဆောက်မယ့် ADT များ
| ADT | သတ်မှတ်ထားတဲ့ စည်းမျဉ်း | အဓိက operation များ |
|---|---|---|
| Linked List | ချိတ်ဆက်ထားတဲ့ node တွေကို တစ်ကြောင်းတည်း အစဉ်လိုက် တန်းစီထားပါတယ် | insert, delete, traverse, search |
| Stack (အပေါ်ကနေပဲ ထည့်၊ ထုတ်တဲ့ အထပ်) | Last In, First Out (LIFO: နောက်ဆုံးဝင်တာ အရင်ထွက်) | push, pop, peek |
| Queue (အရင်ထည့်တာ အရင်ထွက်တဲ့ တန်း) | First In, First Out (FIFO: အရင်ဝင်တာ အရင်ထွက်) | enqueue, dequeue, peek |
| Binary Search Tree (ဘယ်ဘက် ငယ်၊ ညာဘက် ကြီးတဲ့ binary tree) | Left child < parent < right child (ဘယ်ဘက် အောက်က node < အပေါ်က node < ညာဘက် အောက်က node) | insert, delete, search, traverse |
| Set (မထပ်တဲ့ element တွေ စုထားတဲ့ အစု) | အစဉ် မရှိဘဲ မထပ်တဲ့ element တွေပဲ ပါပါတယ် | add, remove, contains, union, intersection |
| HashMap (Java ရဲ့ key-value hash table) | Hashing (key ကို index အဖြစ် ပြောင်းခြင်း) နဲ့ သိမ်းထားတဲ့ key-value pair (key နဲ့ သူ့တန်ဖိုး အတွဲ) တွေ | put, get, remove, containsKey |
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: Contract (လိုက်နာရမယ့် သဘောတူချက်) အဖြစ် ADT
ADT တစ်ခုက contract တစ်ခုကို သတ်မှတ်ပေးပါတယ်: ဘယ် implementation မဆို ပေးရမယ့် operation အစု တစ်ခုပါ။ Java မှာ ဒါကို interface (class တစ်ခု implement လုပ်ရမယ့် method စာရင်း) နဲ့ သဘာဝကျကျ ဖော်ပြပါတယ်။
// The ADT contract: what operations a SimpleList must support
public interface SimpleList {
void add(String item);
String get(int index);
int size();
boolean contains(String item);
}
# The ADT contract: what operations a SimpleList must support.
# Python has no "interface" keyword - the contract is written as a
# class skeleton whose method bodies are left for implementations to fill in.
class SimpleList():
def add(self, item):
pass # code missing
def get(self, index):
pass # code missing
def size(self):
pass # code missing
def contains(self, item):
pass # code missing
ဒီ interface က item တွေကို ဘယ်လို သိမ်းလဲ ဆိုတာ ဘာမှ မပြောပါဘူး။ မတူတဲ့ class (object တွေ ဖန်တီးဖို့ ပုံစံခွက်) နှစ်ခုက ဒီ interface ကို လုံးဝ မတူတဲ့ နည်းလမ်းတွေနဲ့ implement လုပ်နိုင်ပါတယ်:
// Implementation 1: backed by an array (static structure)
public class ArrayBasedList implements SimpleList {
private String[] data;
private int count;
public ArrayBasedList(int capacity) {
data = new String[capacity];
count = 0;
}
public void add(String item) {
data[count] = item;
count++;
}
public String get(int index) {
return data[index];
}
public int size() {
return count;
}
public boolean contains(String item) {
for (int i = 0; i < count; i++) {
if (data[i].equals(item)) {
return true;
}
}
return false;
}
}
# Implementation 1: backed by a fixed-size list (static structure).
# There is no "implements" keyword - providing the same methods
# fulfils the SimpleList contract.
class ArrayBasedList():
def __init__(self, capacity):
self._data = [None] * capacity # fixed block of slots, like the Java array
self._count = 0
def add(self, item):
self._data[self._count] = item
self._count = self._count + 1
def get(self, index):
return self._data[index]
def size(self):
return self._count
def contains(self, item):
for i in range(self._count):
if self._data[i] == item: # == compares string content (Java needs .equals)
return True
return False
အဓိက အယူအဆ: SimpleList ကို သုံးဖို့ ရေးထားတဲ့ code မှန်သမျှက ဘယ် implementation နဲ့မဆို အလုပ်လုပ်ပါတယ်။ အတွင်းမှာ array သုံးလား၊ linked list သုံးလား ဆိုတာကို caller (ခေါ်တဲ့ method) က ဘယ်တော့မှ မသိပါဘူး (သိဖို့လည်း မလိုပါဘူး)။
ဥပမာ 2: Interface တူပေမယ့် Trade-off (တစ်ခု ရဖို့ တစ်ခု အလျှော့ပေးရတာ) မတူခြင်း
public class AdtDemo {
public static void printAll(SimpleList list) {
// This method works with ANY SimpleList implementation
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
SimpleList roster = new ArrayBasedList(50);
roster.add("Aiko");
roster.add("Ben");
roster.add("Carlos");
printAll(roster); // prints all three names
System.out.println("Contains Ben? " + roster.contains("Ben"));
System.out.println("Size: " + roster.size());
}
}
def print_all(items):
# This function works with ANY class that fulfils the SimpleList contract
for i in range(items.size()):
print(items.get(i))
roster = ArrayBasedList(50)
roster.add("Aiko")
roster.add("Ben")
roster.add("Carlos")
print_all(roster) # prints all three names
print("Contains Ben?", roster.contains("Ben")) # Python prints True/False with a capital letter
print("Size:", roster.size())
Output (program က ထုတ်ပြတဲ့ ရလဒ်):
Aiko
Ben
Carlos
Contains Ben? true
Size: 3
နောက်ပိုင်းမှာ SimpleList ကို implement လုပ်တဲ့ LinkedBasedList ကို ထပ်ရေးရင် printAll ကိုရော interface ကို သုံးတဲ့ တခြား code တွေကိုပါ မပြောင်းဘဲ အစားထိုး သုံးလို့ ရပါတယ်။ သီးခြား implementation တစ်ခုကို အခြေခံပြီး program ရေးမယ့်အစား ADT ကို အခြေခံပြီး ရေးတာရဲ့ လက်တွေ့ အကျိုးကျေးဇူးက ဒါပါပဲ။
ဥပမာ 3: Static နဲ့ Dynamic: Array ရဲ့ ကန့်သတ်ချက်များ
Dynamic structure တွေ ဘာကြောင့် လိုအပ်လဲ ဆိုတာကို ဒီဥပမာက ပြပေးပါတယ်:
public class ArrayLimitDemo {
public static void main(String[] args) {
// Static: must decide size in advance
String[] waitlist = new String[3];
waitlist[0] = "Order-101";
waitlist[1] = "Order-102";
waitlist[2] = "Order-103";
// What if a 4th order arrives?
// waitlist[3] = "Order-104"; // ArrayIndexOutOfBoundsException!
// Inserting in the middle requires shifting everything
// To insert "Order-100" at position 0:
// Must shift [0] -> [1], [1] -> [2], etc. -- O(n) work
System.out.println("Array is full with " + waitlist.length + " slots");
System.out.println("Cannot add more without creating a new, larger array");
}
}
# Static: must decide size in advance
# (a plain Python list would grow on demand - here we mirror a fixed-size array)
waitlist = [None] * 3
waitlist[0] = "Order-101"
waitlist[1] = "Order-102"
waitlist[2] = "Order-103"
# What if a 4th order arrives?
# waitlist[3] = "Order-104" # IndexError: list assignment index out of range
# Inserting in the middle requires shifting everything
# To insert "Order-100" at position 0:
# Must shift [0] -> [1], [1] -> [2], etc. -- O(n) work
print("Array is full with", len(waitlist), "slots")
print("Cannot add more without creating a new, larger array")
Output:
Array is full with 3 slots
Cannot add more without creating a new, larger array
Dynamic structure (linked list လို) မှာတော့ ပုံသေ capacity (ထည့်နိုင်တဲ့ အများဆုံး အရေအတွက်) မရှိပါဘူး: node အသစ် တစ်ခု ဖန်တီးပြီး list ထဲကို ချိတ်ထည့်လိုက်ရုံပါပဲ။ Element တွေကို နေရာ ရွှေ့ဖို့ မလိုပါဘူး။
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. Abstract Data Type (ADT) က ဘာကို ဖော်ပြသလဲ။
Q2. အတွင်းမှာ သိမ်းထားတဲ့ ဒေတာ (internal state) ကို အသုံးပြုသူတွေဆီက ဖုံးထားပေးတာ ADT ရဲ့ ဘယ် ဂုဏ်သတ္တိလဲ။
Q3. အောက်ပါတို့ထဲက ဘယ်ဟာက static data structure ရဲ့ ဂုဏ်သတ္တိ တစ်ခုလဲ။
Q4. ADT တွေမှာ interface ရဲ့ ရည်ရွယ်ချက်က ဘာလဲ။
Q5. ဒေတာ ပမာဏကို ကြိုမသိနိုင်တဲ့အခါ dynamic data structure တွေက array တွေထက် memory ကို ပိုထိထိရောက်ရောက် သုံးတယ်လို့ ဘာကြောင့် ယူဆကြသလဲ။
Q6. Program တစ်ခုက SimpleList ADT ကို သုံးပါတယ်။ အောက်ခံ implementation ကို array ကနေ linked list ကို ပြောင်းလိုက်ပါတယ်။ SimpleList ကို သုံးတဲ့ code မှာ ဘာဖြစ်မလဲ။
Trace Exercise (code ကို တစ်ဆင့်ချင်း လိုက်ကြည့်ခြင်း)
အောက်က code ကို trace (တစ်ဆင့်ချင်း လိုက်ပြီး မှတ်) လုပ်ပြီး operation တစ်ခုစီ ပြီးနောက် တန်ဖိုးတွေကို ဖြည့်ပါ။ အဖြေတွေကို code ထဲကအတိုင်း English နဲ့ ရိုက်ထည့်ပါ (ဥပမာ true ဒါမှမဟုတ် false)။
SimpleList items = new ArrayBasedList(5);
items.add("Red");
items.add("Green");
items.add("Blue");
items = ArrayBasedList(5)
items.add("Red")
items.add("Green")
items.add("Blue")
| ဒီ operation ပြီးနောက် | size() | get(0) | contains("Green") |
|---|---|---|---|
| new ArrayBasedList(5) | -- | ||
| add("Red") | |||
| add("Green") | Red | ||
| add("Blue") | Red | true |
Code Completion (code ကွက်လပ် ဖြည့်ခြင်း)
Stack ရဲ့ စံ operation တွေကို ပေးတဲ့ SimpleStack ADT အတွက် Java interface ကို ဖြည့်ပါ။
Stack ADT ရဲ့ contract ကို သတ်မှတ်ဖို့ ကျန်နေတဲ့ method signature (method ရဲ့ နာမည်နဲ့ parameter type တွေ) တွေကို ဖြည့်ပါ:
public interface SimpleStack {
void (String item); // add to top
String (); // remove from top
String (); // view top without removing
boolean isEmpty();
int (); // number of elements
}
အတွင်းက array ကို traverse လုပ်ပြီး list ထဲမှာ item တစ်ခု ပါမပါ စစ်တဲ့ code ကို ဖြည့်ပါ:
contains method ကို implement လုပ်ဖို့ ကွက်လပ်တွေကို ဖြည့်ပါ:
public boolean contains(String item) {
for (int i = 0; i < ; i++) {
if (data[i].(item)) {
return ;
}
}
return false;
}
Spot the Error (အမှား ရှာခြင်း)
ဒီ add method က item တွေကို အစဉ်လိုက် သိမ်းရမှာ ဖြစ်ပေမယ့် item တိုင်းက index 0 မှာပဲ ရောက်နေပါတယ်:
မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
ဒီ contains method က list ထဲမှာ item ရှိနေရင်တောင် ဘယ်တော့မှ ရှာမတွေ့ပါဘူး:
Line 3 အတွက် မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Predict the Output (output ကို ကြိုခန့်မှန်းခြင်း)
ဒီ code က ဘာကို print ထုတ်သလဲ။
SimpleList fruits = new ArrayBasedList(10);
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
System.out.println(fruits.size());
System.out.println(fruits.get(1));
System.out.println(fruits.contains("Mango"));Output ကို အတိအကျ ရိုက်ထည့်ပါ:
ဒီ code က ဘာကို print ထုတ်သလဲ။
SimpleList colors = new ArrayBasedList(5);
colors.add("Red");
colors.add("Green");
colors.add("Blue");
System.out.println(colors.contains("Red"));
System.out.println(colors.contains("Yellow"));Output ကို အတိအကျ ရိုက်ထည့်ပါ:
Practice Exercises (လေ့ကျင့်ခန်းများ)
Core (အခြေခံ အဆင့်)
- ADT သုံးခုကို သတ်မှတ်ပါ။ အောက်ပါ တစ်ခုချင်းစီ (Stack, Queue, Set) အတွက် interface ကို ရေးပါ: တစ်ခုစီမှာ ပါရမယ့် operation တွေကို စာရင်းပြုစုပြီး operation တစ်ခုစီ ဘာလုပ်လဲ ဆိုတာကို အကျဉ်း ဖော်ပြပါ။ Code ရေးဖို့ မလိုပါဘူး။
- Static နဲ့ Dynamic နှိုင်းယှဉ်ချက်။ Array နဲ့ linked list ကို စံ ငါးခုနဲ့ နှိုင်းယှဉ်တဲ့ ဇယား တစ်ခု ပြုလုပ်ပါ: အရွယ်အစား ပြောင်းလွယ်မှု၊ memory သုံးစွဲမှု၊ ထည့်တဲ့ မြန်နှုန်း၊ index နဲ့ ယူသုံးခြင်း နဲ့ ဖျက်ရ လွယ်ကူမှု။
- လက်တွေ့ ဘဝက ADT များ။ ADT လို အလုပ်လုပ်တဲ့ လက်တွေ့ ဘဝက စနစ် သုံးခု (ဥပမာ ရုပ်ရှင်ရုံမှာ လက်မှတ် ဝယ်ဖို့ တန်းစီတာ) ကို Identify (ဖြစ်နိုင်တဲ့ အဖြေတွေထဲက ရွေးပြီး ဖော်ပြပါ) လုပ်ပါ။ တစ်ခုစီအတွက် ဘယ် ADT နဲ့ ဆင်တူလဲ ဆိုတာ ဖော်ပြပြီး အဲဒီ လက်တွေ့ စနစ်က ပေးတဲ့ operation တွေကို စာရင်းပြုစုပါ။
Extension (တိုးချဲ့ အဆင့်)
- SimpleQueue interface ကို ဒီဇိုင်းဆွဲပါ။
enqueue,dequeue,peek,isEmptyနဲ့sizemethod တွေပါတဲ့SimpleQueueလို့ ခေါ်တဲ့ Java interface တစ်ခုကို ရေးပါ။ ပြီးရင် array သုံးပြီး ဘယ်လို implement လုပ်မလဲ ဆိုတာကို ရှင်းပြတဲ့ စာပိုဒ် တိုတို တစ်ပိုဒ် ရေးပါ။ - Trade-off ခွဲခြမ်းစိတ်ဖြာချက်။ သီချင်း app တစ်ခုက playlist တစ်ခုကို သိမ်းထားပါတယ်။ User က သီချင်းတွေကို အဆုံးမှာ မကြာခဏ ထည့်ပြီး အလယ်ကနေ မကြာခဏ ဖယ်ထုတ်ပါတယ်။ ဘယ် implementation (array ဒါမှမဟုတ် linked list) ကို အကြံပြုမလဲ၊ ဘာကြောင့်လဲ။ Time complexity (input ကြီးလာရင် ကြာချိန် တိုးပုံ) ကို ကိုးကားပြီး သင့်အဖြေကို Justify (ဘာကြောင့် ရွေးတာလဲ အကြောင်းပြချက်နဲ့ ပြပါ) လုပ်ပါ။
Challenge (စိန်ခေါ်မှု အဆင့်)
- Implementation အမျိုးမျိုး။ ဥပမာ 1 က
SimpleListinterface ကို implement လုပ်တဲ့ Java class နှစ်ခုကို အပြည့်အစုံ ရေးပါ: တစ်ခုက array ကို အခြေခံထားပြီး (အပေါ်မှာ ပြထားပြီးသား) နောက်တစ်ခုကjava.util.ArrayListကို အခြေခံထားပါ။ Test code တစ်ခုတည်းက implementation နှစ်ခုလုံးနဲ့ အလုပ်လုပ်ကြောင်း ပြပါ။ - ကိုယ်ပိုင် ADT တစ်ခု ဒီဇိုင်းဆွဲပါ။
addBook,removeBook,searchByTitle,searchByAuthorနဲ့listAllလို operation တွေ ပေးတဲ့ “Library Catalog” (စာကြည့်တိုက်ရဲ့ စာအုပ်စာရင်း) အတွက် ADT တစ်ခုကို Design (အစီအစဉ် ဒါမှမဟုတ် model တစ်ခု ရေးဆွဲပါ) လုပ်ပါ။ Java interface ကို ရေးပါ။ ပြီးရင် အတွင်းမှာ ဒေတာ သိမ်းဖို့ မတူတဲ့ နည်းလမ်း နှစ်မျိုးကို Explain (ရှင်းပြပါ) လုပ်ပြီး သူတို့ရဲ့ trade-off တွေကို Discuss (အချက် အမျိုးမျိုးကို ချိန်ဆပြီး ဆွေးနွေးပါ) လုပ်ပါ။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Encapsulation: ADT တွေက အတွင်း ဒေတာကို public interface (အပြင်ကနေ သုံးခွင့်ရှိတဲ့ interface) နောက်မှာ ဖုံးထားတဲ့ အယူအဆပေါ်မှာ အခြေခံပါတယ်
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Interfaces: Java interface တွေက ADT contract တွေကို code နဲ့ ဖော်ပြတဲ့ နည်းလမ်းပါ
- ဆက်စပ် ခေါင်းစဉ်: Stacks နဲ့ Queues: ဒါတွေကို ADT အဖြစ် သုံးခဲ့ပြီးပါပြီ၊ အခု အစကနေ ကိုယ်တိုင် တည်ဆောက်ပါမယ်
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: Linked Lists: node တစ်ခုချင်း ကိုယ်တိုင် implement လုပ်ရမယ့် ပထမဆုံး dynamic data structure