學習軌道
/
Julia
Julia
/
練習
/
Elyse 的魔法道具
Elyse 的魔法道具

Elyse 的魔法道具

學習練習

簡介

Julia 的核心目標之一,就是能快速且有效率地對數值資料進行運算。 _大量_的數值資料。

一般來說,這些資料會儲存在陣列(或某種相關的型別)中,所以說陣列是 Julia 語言的核心,一點也不為過。

陣列的大小可以任意(只受限於硬體的記憶體),維度也可以任意多。

這篇入門概念聚焦在一維陣列的基礎,也就是所謂的向量。

建立向量

在 Julia 中,向量是一串有順序的值,可以透過索引編號來存取。

建立向量最簡單的方法,就是把值列在方括號裡:

julia> num_vec = [1, 4, 9]
3-element Vector{Int64}:
 1
 4
 9

julia> str_vec = ["arrays", "are", "important"]
3-element Vector{String}:
 "arrays"
 "are"
 "important"

Vector 的型別會與每個元素的型別一致。

所以向量必須是同質的(所有元素的型別都相同)嗎?

某種程度上,是的,而且如果你想要最好的效能,建議盡量朝這個方向做。 不過,Julia 在必要時可以透過 Any 型別繞過這個限制:

julia> mixed_vector = [1, "str", 'c']
3-element Vector{Any}:
 1
  "str"
  'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)

建立空向量時,Julia 預設的元素型別是 Any,但你可以在空陣列上標註想要的元素型別,把它定義得更明確。

julia> empty_vec = []
Any[]

julia> empty_int_vec = Int64[]
Int64[]

請閱讀並記住這條規則:

  • 在 Julia 中,索引預設從 1 開始,而不是 0。

用過其他資料科學語言(R、Matlab、Fortran……)的人對這點應該很熟悉,但對有 C 類型語言背景的資訊科學家來說,可能會覺得很震撼。

除此之外,索引的運作方式就和你想的一樣:把它們放進方括號裡就行了:

squares = [0, 1, 4, 9, 16]
squares[1]  # 0
squares[3]  # 4
squares[begin]  # 0 ("begin" is synonym for 1)
squares[end]  # 16 ("end" is synonym for length(squares))

請注意,用 end(非常實用)和 begin(大概沒那麼實用)來索引有多方便。

用 Python 寫程式的人可能會好奇負索引。 別這麼想,Julia 並沒有負索引,用了會拋出BoundsError,任何小於 1 或大於length(squares)的索引也一樣。

向量運算

Julia 的向量是_可變的_:我們可以改變個別元素的內容。

julia> vals = [1, 3, 5, 7]
4-element Vector{Int64}:
 1
 3
 5
 7

julia> vals[2] = 4  # reassign the value of this element
4

# Only the value at position 2 changes:
julia> vals
4-element Vector{Int64}:
 1
 4
 5
 7

有許多函式可以用來操作向量,不過 Julia 的文件把它們一般化為「collection」,而不只是向量。

注意,依照慣例,會修改輸入的函式名稱會帶有 !。 編譯器不會強制執行這點,但這在 Julia 的世界裡是非常_強烈_的慣例。

以下是幾個實用的函式:

  • 要把值加到向量末端,用push!()。
  • 要移除最後一個值,用pop!()。
  • 要操作向量的開頭,對應的函式是pushfirst!()和popfirst!()。
  • 要在任何位置插入或移除元素,有insert!()和deleteat!()。
julia> vals = [1, 3]
2-element Vector{Int64}:
 1
 3

julia> push!(vals, 5, 6)  # can add multiple values
4-element Vector{Int64}:
 1
 3
 5
 6

julia> pop!(vals)  # mutates vals, return popped value
6

julia> vals
3-element Vector{Int64}:
 1
 3
 5

說明

身為見習魔術師,Elyse 需要練習一些基本功。 她有一疊卡片,想要操作它們。

為了方便起見,她只用 1 到 10 的卡片,所以她的堆疊可以用一個數字向量來表示。 某張卡片的位置對應到向量中的索引。

1. 從堆疊取出一張卡片

要挑一張卡片,就從給定的堆疊中回傳索引position的卡片。

julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> get_item(stack, position)
4

2. 替換堆疊中的一張卡片

施展一點手法,把索引position的卡片替換成提供的替代卡片。 回傳調整後的堆疊。

julia> stack = [1, 2, 4, 1];
julia> position = 3;
julia> replacement_card = 6;
julia> set_item!(stack, position, replacement_card)
[1, 2, 6, 1]

3. 在堆疊頂端插入一張卡片

在堆疊頂端插入一張新卡片,讓它憑空出現。 回傳調整後的堆疊。

julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_top!(stack, new_card)
[5, 9, 7, 1, 8]

4. 從堆疊移除一張卡片

從堆疊中移除指定position的卡片,讓它消失。 回傳調整後的堆疊。

julia> stack = [3, 2, 6, 4, 8];
julia> position = 3;
julia> remove_item!(stack, position)
[3, 2, 4, 8]

5. 移除堆疊頂端的卡片

移除堆疊頂端的卡片,讓它消失。 回傳調整後的堆疊。

julia> stack = [3, 2, 6, 4, 8];
julia> remove_item_from_top!(stack)
[3, 2, 6, 4]

6. 在堆疊底部插入一張卡片

在堆疊底部插入一張新卡片,讓它憑空出現。 回傳調整後的堆疊。

julia> stack = [5, 9, 7, 1];
julia> new_card = 8;
julia> insert_item_at_bottom!(stack, new_card)
[8, 5, 9, 7, 1]

7. 移除堆疊底部的卡片

移除堆疊底部的卡片,讓它消失。 回傳調整後的堆疊。

julia> stack = [8, 5, 9, 7, 1];
julia> remove_item_at_bottom!(stack)
[5, 9, 7, 1]

8. 檢查堆疊的大小

檢查堆疊的大小是否等於stack_size。

julia> stack = [3, 2, 6, 4, 8];
julia> stack_size = 4;
julia> check_size_of_stack(stack, stack_size)
false
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Julia Exercism

準備好開始 Elyse 的魔法道具 了嗎?

註冊 Exercism,透過 35 個概念128 個練習 和真人引導來學習並精通 Julia,全部免費。