什麼是演算法以及為什麼要懂一點演算法?

演算法

前言

這一篇簡單聊一下什麼是演算法以及為什麼要懂一點演算法就好,算是簡單的入門文章,因此不會提到太多複雜的東西。

什麼是演算法?

首先在說明什麼是演算法之前,我們要先認識兩個名詞,分別是

  • 時間
  • 空間

為什麼要先認識這兩個名詞呢?其主要原因是因為演算法是為了解決在有限的時間與空間內提供出最佳的解決方案,因此才會提到這兩個名詞。

那麼什麼是「時間」呢?其實就代表著當你做這件事情時,所需要花費的時間,假設來講你寫一篇文章要花費 1 小時,那麼這個時間就是 1 小時,這邊所指的時間就是這個意思。

而空間通常泛指佔用的記憶體空間,假設來講,如果一張圖片所需要的記憶體空間是 1MB,那麼這個空間就是 1MB,這邊所指的空間。

那麼演算法很常用嗎?其實演算法本身就一直存在於你我的身邊,舉例來講,平常你在滑社群平台時,應該都會看到有人留言說

演算法帶我看到這一部影片
演算法帶我看到這個留言、文章

除非你完全沒有在使用網路。

那麼演算法其實是在指一個被定義好的、電腦可以執行指令或步驟,並且在有限的時間與空間內,可以解決一個問題的方法,這就稱之為演算法。

上面太難懂的話,你可以把演算法想像成一個步驟概念,用這個步驟可以解決一個問題,而這個步驟就是演算法,當然演算法不局限於電腦,只要是可以解決問題的步驟,都可以稱之為演算法。

舉例生活面一點的事情來講,以做一道炒空心菜來講,它的步驟可以是…

  1. 準備一個鍋子
  2. 放入適量的油
  3. 放入空心菜
  4. 放入適量的鹽巴
  5. 等待空心菜熟透
  6. 拿起空心菜
  7. 放入盤子
  8. 完成

那麼這個步驟就是演算法,而這個演算法可以解決「炒空心菜」這個問題。

當然「炒空心菜」的演算法不只這一種,你可以用其他的演算法來解決這個問題,例如蝦醬炒空心菜、蒜頭炒空心菜等等,這些都是不同的演算法,只是步驟不同而已。

為什麼要懂一點演算法?

那麼認識了基本演算法概念之後,接下來我們就要來提一下為什麼要懂一點演算法。

接下來所有的演算法都是以電腦為主,而本篇也會以 JavaScript 為主要語言來做說明。

首先,前面有提到演算法會是一系列的步驟,最終會完成一個目標,但是這個目標我們會套入時間與空間的概念,也就是說,我們會針對演算法去做分析。

那麼為什麼要分析演算法呢?舉例來講假設有兩個相同的演算法,而這兩個演算法最終的結果都是會得到相同的結果,那麼我們就會去比較這兩個演算法分別花了多少時間與空間,而這個時間與空間就是演算法中的「時間複雜度」與「空間複雜度」。

那麼單看文字去空談演算法理論是稍微有一點難理解,所接下來讓我們看一下範例程式碼,從範例程式碼去學習演算法

1
2
3
4
5
6
7
const sum1 = (n) => {
let total = 0;
for (let i = 1; i <= n; i++) {
total += i;
}
return total;
}

這個程式碼用途是什麼呢?它可以將我們丟進去的數字作加總,舉例來講,如果我丟進去了 5,那麼它會從 1 + 2 + 3 + 4 + 5 回傳 15

sum1

那麼接下來我們來看另一種寫法

1
const sum2 = (n) => (n * (n + 1)) / 2;

sum2

第二種寫法跟第一種寫法比起來簡潔許多,但是我們可以得到相同的結果,而第二種寫法就是套用了數學公式去解決這個問題。

那麼通常我們再寫演算法時,我們都會去分析哪一個才是最佳演算法,那麼該怎麼分析呢?這時候就會使用剛剛前面所提到的「時間複雜度」與「空間複雜度」的概念去分析。

首先先講時間複雜度,時間複雜度就是指這個演算法花了多少時間去執行,所以上方的程式碼我們就可以使用 console.timeconsole.timeEnd 來計算花了多少時間,接著這邊我們會刻意丟給 n 一個很大的數字,這樣才能看出來差異

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const sum1 = (n) => {
let total = 0;
for (let i = 1; i <= n; i++) {
total += i;
}
return total;
}
console.time('sum1');
sum1(500000);
console.timeEnd('sum1');

const sum2 = (n) => (n * (n + 1)) / 2;
console.time('sum2');
sum2(500000);
console.timeEnd('sum2');

time

我們可以看到 sum1 所花費的時間會比 sum2 還要多,那麼這時候我們就可以說 sum2 的時間複雜度會比 sum1 來得低,因此我們就可以說 sum2 的演算法會比 sum1 來得好。

因此一個好的演算法基本上就是看它所花的時間以及佔用的記憶體空間。

但是這邊要注意一件事情,用計時的方式去分析演算法的快慢並不是一個好的方式,如果你有嘗試不停的呼叫 sum1(500000); 你會發現每一次出現的時間都不同,除此之外每一台電腦的效能、規格都不同,因此使用計時的方式去分析演算法的好壞並不是正確的做法,只是一個單純的參考而已。

那麼該如何正確分析一個演算法的好壞呢?這時候就會使用到所謂的「Big O」概念,這個概念會將演算法的時間複雜度與空間複雜度做一個分析,而這個分析的方式就是使用「Big O」符號來表示,只是如果這一篇還提到 Big O 的話會變得太複雜,所以這一篇就只是簡單認識一下什麼是演算法以及為什麼要懂一點演算法而已。

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你可以也可以請我「喝一杯咖啡(Donate)」。

Buy Me A Coffee Buy Me A Coffee

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ