學習軌道
/
Crystal
Crystal
/
練習
/
Chaitana 的巨型雲霄飛車
Chaitana 的巨型雲霄飛車

Chaitana 的巨型雲霄飛車

學習練習

簡介

陣列是常見的資料結構。 因此,有一系列方法可以用來處理陣列。 其中包含排序、反轉、插入等許多操作。

有些方法是破壞性的,這表示它們會修改原始陣列。 其他方法則是非破壞性的,也就是說它們會回傳一個新陣列,不會修改原本的陣列。

以下是處理陣列時最常用到的幾個方法:

insert

當你要在陣列中插入元素時,可以使用 insert方法,它接受一個索引和一個元素作為引數。 元素會被插入到指定的索引位置,陣列其餘的部分則會向右移動。 如果索引超出範圍,就會引發IndexError。

numbers = [1, 2, 3]
numbers.insert(1, 4)
numbers # => [1, 4, 2, 3]

numbers.insert(5, 5) # => Error: Index out of bounds (IndexError)

delete

當你想從陣列中刪除特定的元素時,可以使用 delete方法,它接受一個元素作為引數。 這個方法會回傳被移除的元素。 如果元素不存在於陣列中,則會回傳nil。

numbers = [1, 2, 3]
numbers.delete(2) # => 2
numbers           # => [1, 3]

first 與 last

當你想取得陣列的第一個或最後一個元素時,可以使用 first和 last方法。 這些方法接受一個選用引數,用來指定要回傳多少個元素。 相較於使用索引0或-1,或使用範圍,這樣可以提升可讀性。 如果陣列是空的,就會引發Enumerable::EmptyError。

numbers = [1, 2, 3]
numbers.first # => 1
numbers.last  # => 3

numbers.first(2) # => [1, 2]
numbers.last(2)  # => [2, 3]

empty_array = [] of Int32
empty_array.last # => Error: Empty enumerable (Enumerable::EmptyError)

reverse

當你想反轉陣列時,可以使用 reverse方法,它會回傳一個元素順序相反的新陣列。 要注意的是,reverse會回傳新陣列,並不會修改原本的陣列。 如果你想修改原本的陣列,可以在方法名稱結尾加上!。

numbers = [1, 2, 3]
numbers.reverse # => [3, 2, 1]
numbers         # => [1, 2, 3]

numbers.reverse! # => [3, 2, 1]
numbers          # => [3, 2, 1]

Concat(+)

當你想把物件加入陣列時,<<這個附加方法很好用。 不過,當要合併兩個陣列時,可以使用 +運算子,它會回傳一個包含兩個陣列元素的新陣列。

[1, 2] + [3, 4] # => [1, 2, 3, 4]

如果你把一個陣列附加到另一個陣列,該陣列會以單一元素的形式加入。

[1, 2] << [3, 4] # => [1, 2, [3, 4]]

empty?

當你要檢查陣列是否為空時,可以使用 empty?方法,如果陣列是空的就回傳true,否則回傳false。 相較於用0來檢查陣列長度,這樣可以提升可讀性。

[].empty? # => true
[1, 2, 3].empty? # => false

index

當你想取得陣列中某個元素的索引時,可以使用 index方法,它接受一個元素作為引數。 如果元素不存在於陣列中,則會回傳nil。

numbers = [1, 2, 3]
numbers.index(2) # => 1

size

當你想知道陣列中有多少個元素時,可以使用 size方法。

numbers = [1, 2, 3]
numbers.size # => 3

count

當你想計算某個元素在陣列中出現的次數時,可以使用 count方法。

fruits = ["apple", "banana", "apple"]
fruits.count("apple")      # => 2
fruits.count("banana")     # => 1
fruits.count("watermelon") # => 0

sort

當你想排序陣列時,可以使用 sort方法,它會回傳一個元素已排序的新陣列。 和reverse一樣,這個方法會回傳新陣列,並不會修改原本的陣列。

numbers = [3, 2, 1]
numbers.sort # => [1, 2, 3]
numbers      # => [3, 2, 1]

numbers.sort! # => [1, 2, 3]
numbers       # => [1, 2, 3]

說明

Chaitana 擁有一座非常受歡迎的主題樂園。 她在景觀優美的園區正中央只有一項遊樂設施:世界最巨大的雲霄飛車(TM)。 雖然只有這一項設施,世界各地的人還是遠道而來,為了有機會搭乘 Chaitana 的超級雲霄飛車,甘願排上好幾個小時。

這項設施有兩條佇列,各自以array表示:

  1. 一般佇列
  2. 快速通關佇列(又稱 Fast-track),在這裡人們額外付費以優先入場。

有人請你寫一些程式碼,以便更好地管理樂園裡的遊客。 你必須盡快實作下列函式,免得遊客(還有你老闆 Chaitana!)開始不耐煩。

1. 將人員加入佇列

定義 ColossalCoaster.add_to_queue 方法,它接受 4 個引數 <express_queue>, <normal_queue>, <ticket_type>, <person_name>,並回傳已加入該人員姓名的對應佇列。

  1. <ticket_type> 是 Int32,其中 1 代表 express_queue,0 代表 normal_queue。
  2. <person_name> 是要加入對應佇列的人員姓名(型別為 String)。
express_queue = ["Tony", "Bruce"]
normal_queue = ["RobotGuy", "WW"]
ColossalCoaster.add_to_queue(express_queue, normal_queue, 1, "RichieRich")
# => ["Tony", "Bruce", "RichieRich"]

2. 我的朋友在哪裡?

有一個人比較晚到樂園,想加入朋友們正在排的佇列。 但他不知道朋友站在哪裡,而且手機也收不到訊號,沒辦法打電話給他們。

定義 ColossalCoaster.find_my_friend 方法,它接受 2 個引數 queue 和 friend_name,並回傳該人員姓名在佇列中的位置。

  1. <queue> 是正在排隊的人所組成的 array。
  2. <friend_name> 是你要找出其索引(在佇列中的位置)的朋友姓名。
ColossalCoaster.find_my_friend(["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], "Steve")
# => 1

3. 我可以加入他們嗎?

既然已經找到朋友了(在上述的任務 #2),這位晚到的人想在朋友排隊的位置加入他們。 定義 ColossalCoaster.add_with_friends 方法,它接受 3 個引數 queue、friend_name 和 person_name。

  1. <queue> 是正在排隊的人所組成的 array。
  2. <friend_name> 是要插入其位置的朋友姓名。
  3. <person_name> 是要插入該索引位置的人員姓名。

回傳已加入這位晚到者姓名的佇列。

ColossalCoaster.add_with_friends(["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], "Steve", "Bucky")
# => ["Natasha", "Bucky", "Steve", "T'challa", "Wanda", "Rocket"]

4. 佇列裡的討厭鬼

你剛從佇列那邊聽說,有個很討厭的人又推人、又大叫,還到處鬧事。 你得把這個壞傢伙趕出去,因為他行為太差!

定義 ColossalCoaster.remove_from_queue 方法,它接受 2 個引數 queue 和 person_name。

  1. <queue> 是正在排隊的人所組成的 array。
  2. <person_name> 是要被趕出去的人員姓名。

回傳已移除那位討厭鬼姓名的佇列。

ColossalCoaster.remove_from_queue(["Natasha", "Steve", "Eltran", "Wanda", "Rocket"], "Eltran")
# => ["Natasha", "Steve", "Wanda", "Rocket"]

5. 排序佇列

為了管理上的需求,你需要把指定佇列中的所有姓名依字母順序排列。

定義 ColossalCoaster.sorted_queue 方法,它接受 1 個引數 queue(也就是正在排隊的人所組成的 array)。 這個方法應該回傳array排序後的副本。

ColossalCoaster.sorted_queue(["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
# => ['Eltran', 'Natasha', 'Natasha', 'Rocket', 'Steve']
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Crystal Exercism

準備好開始 Chaitana 的巨型雲霄飛車 了嗎?

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