<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ThutaMinThway</title>
    <description>The latest articles on DEV Community by ThutaMinThway (@thuta21).</description>
    <link>https://dev.to/thuta21</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1067980%2F6f5fcbdb-1775-4a9a-9402-319e327d43fb.png</url>
      <title>DEV Community: ThutaMinThway</title>
      <link>https://dev.to/thuta21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thuta21"/>
    <language>en</language>
    <item>
      <title>BigO (Big Oh) Notation</title>
      <dc:creator>ThutaMinThway</dc:creator>
      <pubDate>Sun, 21 Jul 2024 07:43:10 +0000</pubDate>
      <link>https://dev.to/thuta21/bigo-big-oh-notation-41dk</link>
      <guid>https://dev.to/thuta21/bigo-big-oh-notation-41dk</guid>
      <description>&lt;p&gt;သာမန်တွေးကြည့်ရင် ကျွန်တော်တို့အသုံးပြုနေတဲ့ device တွေရဲ့ specification ပေါ်မူတည်ပြီး ဘယ်ဟာက မြန်တယ်၊ မမြန်ဘူး စမ်းကြည့်လို့ရနိုင်ပါတယ်။ ဒါပေမဲ့လည်း algorithm တစ်ခုကိုတိုင်းတာဖို့ ဒီလိုစမ်းကြည့်လို့မရသေးပါဘူး။&lt;/p&gt;

&lt;p&gt;BigO Notation (Big Oh Notation) ဆိုတာ input size ဘယ်လောက်ရှိသလဲပေါ်မူတည်ပြီး algorithm ရဲ့ complexity ကို တိုင်းတာတာပါ။ Complexity မှာ အဓိကအားဖြင့် time နဲ့ space complexity ဆိုပြီး ၂မျိုးရှိတယ်။&lt;/p&gt;

&lt;p&gt;Space Complexity&lt;br&gt;
ပြသာနာ တစ်ခုကိုရှင်းဖို့ algorithm / program ကိုသုံးရင် memory ဘယ်လောက်ယူလဲကို ဆိုလိုတာပါ။&lt;/p&gt;

&lt;p&gt;Time Complexity&lt;br&gt;
Algorithm ရဲ့ run-time ဘယ်လောက်ရှိသလဲကို တွက်တာ။&lt;/p&gt;

&lt;p&gt;BigO ကို တွက်တဲ့နေရာမှာ common complexities တွေ ရှိတယ်။&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Constant | O(1) — Excellent/Best (constant time တစ်ကြိမ်ပဲလုပ်ရတဲ့အတွက် input size ဘယ်လောက်ရှိလည်း တွက်ရမယ့် calculation က အရေးမကြီးတော့ဘူး)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logarithm | O(log n) — Good (Calculation ကို တစ်ဝက်စီပိုင်းပိုင်းပြီးလုပ်ဆောင်ရတာ)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linear | O(n) — Fair (Algorithm တစ်ခုကို single loop လုပ်ပြီး linear time နဲ့ရှာရတာ)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O(n log n) — Bad (log linear complexity | binary sorting algorithm တွေမှာသုံးမယ်)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;O(n²), O(2^n) and O(n!) — Horrible/Worst (Quadratic , Exponential time complexity ဖြစ်ပြီး loop after loop လုပ်တယ်)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;... &lt;/p&gt;

&lt;p&gt;*&lt;em&gt;O(1) — Constant&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Constant time တစ်ကြိမ်ပဲလုပ်ရတဲ့အတွက် algorithm တစ်ခုကို တွက်တဲ့နေရာမှာ input size က အရေးမကြီးတော့ပါဘူး။ ဥပမာပေးရရင် array တစ်ခုရှိတယ်။ Array ထဲမှာ element တွေအများကြီးရှိတယ်။ ဒါပေမယ့် ပထမဆုံး element ကိုလိုချင်တယ်ဆိုရင်…&lt;/p&gt;

&lt;p&gt;`const names = ['thuta', 'john', 'christ', 'tony' ...]&lt;/p&gt;

&lt;p&gt;console.log(names[0]) // get first element "thuta"`&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(log n) — Logarithm&lt;/strong&gt;&lt;br&gt;
Logarithm time | O(log n) သည်လည်းပဲ run-time မှာ input size ဘယ်လောက်ဖြစ်ဖြစ် depend မဖြစ်ပေမယ့် input size တစ်ဝက်ကိုတော့ depend ဖြစ်မှာပါ။ ဆိုလိုချင်တာက complexity တွက်တဲ့ step တစ်ဆင့်ချင်းစီမှာ input size က တစ်ဝက်စီ လျော့ကြသွားမှာဖြစ်တယ်။ ဥပမာပေးရရင် binary search ပါ။ Binary search အလုပ်လုပ်ပုံက sorting လုပ်ထားပြီးသား array တစ်ခုရှိမယ်။ Array ထဲမှာ ကိုယ်လိုချင်တဲ့ value ကိုရှာမယ်ဆိုရင် array length ကို တစ်ဝက်အရင်ပိုင်း။ ပြီးရင် ဆက်ရှာ။ ဒီလိုနဲ့ လိုချင်တဲ့ target ရောက်အောင်ထိသွားရမှာပါ။&lt;/p&gt;

&lt;p&gt;&lt;code&gt;numbers = [1,2,3,4,5,6,7,8,9] // target value is 2&lt;br&gt;
  first = 1&lt;br&gt;
   last = 9&lt;br&gt;
    mid = (first + last) / 2&lt;br&gt;
        = (1 + 9) / 2 &lt;br&gt;
        = 5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ဒီနေရာမှာ အလယ်ဖြစ်တဲ့နေရာက 5 ။ လိုချင်တဲ့ value က 2။ ဒီတော့ sorting array ဖြစ်တဲ့အတွက် လိုချင်တဲ့ value နေရာကို ခန့်မှန်းလို့ရတာပေါ့။ ဒီတော့ ၅ ကနေစပြီး ညာဘက်က element တွေမဖြစ်နိုင်တော့ဘူးဆိုတော့ array ဆက်တွက်မယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;numbers = [1,2,3,4] // target value is 2
  first = 1
   last = 4
    mid = (first + last) / 2
        = (1 + 4) / 2 
        = 5 / 2 = 2 // target has reached
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ဒါဆိုရင် လိုချင်တဲ့အဖြေရဖို့ ၂ဆင့်ပဲ တွက်စရာလိုတယ်။&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(n) — Linear&lt;/strong&gt;&lt;br&gt;
Linearly သွားတာဖြစ်တဲ့အတွက် input size များလေလေ algorithm run-time များလာလေလေ။&lt;/p&gt;

&lt;p&gt;ဥပမာပေးရရင် array တစ်ခုရှိတယ်။ element 1 ကနေ 10 ထိရှိတယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const array = [1,2,3,4,5,6,7,8,9,10] 

for (let i = 0; i &amp;lt;= array.length; i ++) {
    console.log('Hello world') // output will be 11 times of "Hello World"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ဒီတော့ ကိုယ်ပေးလိုက်တဲ့ n times အလိုက် အလုပ်လုပ်မယ်။ နောက် example ကြည့်ရအောင်&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const calcFactorial = (n) =&amp;gt; {
  let factorial = 1;
  for (let i = 2; i &amp;lt;= n; i++) {
    factorial = factorial * i;
  }
  return factorial;
};

console.log(calcFactorial(5)); // 120
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5 * 4 * 3 * 2 * 1 = 120 ။ ဆိုတော့ ကျွန်တော်က calcFactorial မှာ input 10 ပေးရင်လည်း&lt;/p&gt;

&lt;p&gt;10 * 9 * 8 * … ဒီလို linearly ဆက်သွားလိမ့်မယ်။&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(n²) — Quadratic&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ကျွန်တော်တို့မှာ locker 5 ခုရှိတယ်။ သော့ ၅ ခုရှိတယ်။ ကျွန်တော်လိုချင်တဲ့ ပစ္စည်းက locker 5 ခုထဲက တစ်ခုမှာထည့်ထားတယ်။ ဒါပေမယ့် ကျွန်တော်က ပစ္စည်းရှိတဲ့နေရာလည်းမသိဘူး။ ဘယ်သော့နဲ့ ဘယ် locker နဲ့ match ဖြစ်လည်းဆိုတာလဲ မသိပြန်ဘူး။ ဆိုတော့ ကျွန်တော်က သော့၅ခုနဲ့ locker ၅ ခုကိုဖွင့်ရပါတော့မယ်။ ဒီလိုဆို 5 * 5 (5²) ပေါ့။&lt;/p&gt;

&lt;p&gt;ဆိုလိုချင်တာက quadratic မှာ input size ထည့်ပြီး လိုချင်တဲ့ targeted value ရဖို့ loop 2 ခါပတ်ရတယ် (n times n) ဒါကြောင့်ဒီအခြေအနေက worst ဖြစ်နေရတာ။ Sample code ကြည့်မယ်ဆိုရင် pair ရှာတဲ့ example မျိုး။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function processPairs(array) {
  const n = array.length;

  for (let i = 0; i &amp;lt; n; i++) {
    for (let j = 0; j &amp;lt; n; j++) {
      const pair = [array[i], array[j]];
      console.log("Processing pair:", pair);
    }
  }
}

const exampleArray = [1, 2, 3, 4];
console.log("Input array:", exampleArray);

processPairs(exampleArray); 

//output

[ 1 , 2 , 3 , 4 ]

[ 1 , 1 ] , [ 1 , 2 ], [ 1 , 3 ], [ 1 , 4 ]

[ 2 , 1 ] , [ 2 , 2 ], [ 2 , 3 ], [ 2 , 4 ]

[ 3 , 1 ] , [ 3 , 2 ], [ 3 , 3 ], [ 3 , 4 ]

[ 4 , 1 ] , [ 4 , 2 ], [ 4 , 3 ], [ 4 , 4 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O(2^n) — Exponential&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Exponential time complexity ဆိုတာ input size တိုးသလောက် algorithm ရဲ့ run-time ကလည်း exponential ratio နဲ့ တိုးပွားတာ ဖြစ်တယ်။ ဒီလိုကိစ္စတွေမှာ loop တစ်ခုပြီးတစ်ခု nested လုပ်ထားရုံတင်မကပဲ recursive algorithm တွေမှာ တွေ့ရတတ်တယ်။&lt;/p&gt;

&lt;p&gt;ဥပမာ binary decision tree တစ်ခုကို traverse လုပ်တာမျိုး၊ အောက်ပါ function မှာ recursive call တွေတွေ့ရမှာ ဖြစ်တယ်။ ဒီမှာ n က 2 ဖြစ်တဲ့အခါ base case ကိုရောက်ဖို့ 2² = 4 times ခေါ်ရမယ်၊ n က 3 ဖြစ်ရင် 2³ = 8 times ခေါ်ရမယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function fibonacci(n) {
    if (n &amp;lt;= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(5)); // Output: 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;O(n!) — Factorial&lt;/strong&gt;&lt;br&gt;
Factorial time complexity ကတော့ input size n ရဲ့ factorial value နဲ့ညီတဲ့ run-time ဖြစ်တယ်။ ဒီအခြေအနေမှာ run-time က အရမ်းမြင့်တက်တတ်တာကြောင့် practical ဖြစ်လို့အသုံးချဖို့အရမ်းခက်ပါတယ်။&lt;/p&gt;

&lt;p&gt;ဥပမာ၊ permutation တွေကို generate လုပ်တဲ့ algorithm တစ်ခုမှာ ကြည့်မယ်ဆိုရင် input size n ရဲ့ permutations အားလုံးကို generate လုပ်ဖို့ n! operations လိုအပ်ပါတယ်။&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function generatePermutations(array) {
    const results = [];

    function permute(arr, memo = []) {
        let cur, memoArr;
        for (let i = 0; i &amp;lt; arr.length; i++) {
            cur = arr.splice(i, 1);
            if (arr.length === 0) {
                results.push(memo.concat(cur));
            }
            permute(arr.slice(), memo.concat(cur));
            arr.splice(i, 0, cur[0]);
        }
        return results;
    }

    return permute(array);
}

console.log(generatePermutations([1, 2, 3])); 
// Output: All permutations of [1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ဒီတော့ BigO Notation ဟာ input size ကြီးသွားလို့ algorithm ရဲ့ efficiency ဘယ်လိုပြောင်းလဲသလဲဆိုတာကိုရှင်းပြတယ်။ Run-time က input size ပေါ်မူတည်ပြီး ဘယ်လိုသက်ရောက်မှုရှိလဲဆိုတာနားလည်ဖို့ BigO ကိုသုံးတယ်။&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
