Bug fixes and improvements (#1318)
* Sync zh and zh-hant versions * Update en/README.md * Add a Q&A for chapter of introduction * Update the callout headers * Sync zh ang zh-hant versions * Bug fixespull/1324/head
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,63 @@
|
||||
import { bold, brightRed } from 'jsr:@std/fmt/colors';
|
||||
import { expandGlob } from 'jsr:@std/fs';
|
||||
import { relative, resolve } from 'jsr:@std/path';
|
||||
|
||||
/**
|
||||
* @typedef {import('jsr:@std/fs').WalkEntry} WalkEntry
|
||||
* @type {WalkEntry[]}
|
||||
*/
|
||||
const entries = [];
|
||||
|
||||
for await (const entry of expandGlob(
|
||||
resolve(import.meta.dirname, './chapter_*/*.js')
|
||||
)) {
|
||||
entries.push(entry);
|
||||
}
|
||||
|
||||
/** @type {{ status: Promise<Deno.CommandStatus>; stderr: ReadableStream<Uint8Array>; }[]} */
|
||||
const processes = [];
|
||||
|
||||
for (const file of entries) {
|
||||
const execute = new Deno.Command('node', {
|
||||
args: [relative(import.meta.dirname, file.path)],
|
||||
cwd: import.meta.dirname,
|
||||
stdin: 'piped',
|
||||
stdout: 'piped',
|
||||
stderr: 'piped',
|
||||
});
|
||||
|
||||
const process = execute.spawn();
|
||||
processes.push({ status: process.status, stderr: process.stderr });
|
||||
}
|
||||
|
||||
const results = await Promise.all(
|
||||
processes.map(async (item) => {
|
||||
const status = await item.status;
|
||||
return { status, stderr: item.stderr };
|
||||
})
|
||||
);
|
||||
|
||||
/** @type {ReadableStream<Uint8Array>[]} */
|
||||
const errors = [];
|
||||
|
||||
for (const result of results) {
|
||||
if (!result.status.success) {
|
||||
errors.push(result.stderr);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Tested ${entries.length} files`);
|
||||
console.log(`Found exception in ${errors.length} files`);
|
||||
|
||||
if (errors.length) {
|
||||
console.log();
|
||||
|
||||
for (const error of errors) {
|
||||
const reader = error.getReader();
|
||||
const { value } = await reader.read();
|
||||
const decoder = new TextDecoder();
|
||||
console.log(`${bold(brightRed('error'))}: ${decoder.decode(value)}`);
|
||||
}
|
||||
|
||||
throw new Error('Test failed');
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
=begin
|
||||
File: my_heap.rb
|
||||
Created Time: 2024-04-19
|
||||
Author: Blue Bean (lonnnnnnner@gmail.com)
|
||||
=end
|
||||
|
||||
require_relative '../utils/print_util'
|
||||
|
||||
### 大頂堆積 ###
|
||||
class MaxHeap
|
||||
attr_reader :max_heap
|
||||
|
||||
### 建構子,根據輸入串列建堆積 ###
|
||||
def initialize(nums)
|
||||
# 將串列元素原封不動新增進堆積
|
||||
@max_heap = nums
|
||||
# 堆積化除葉節點以外的其他所有節點
|
||||
parent(size - 1).downto(0) do |i|
|
||||
sift_down(i)
|
||||
end
|
||||
end
|
||||
|
||||
### 獲取左子節點的索引 ###
|
||||
def left(i)
|
||||
2 * i + 1
|
||||
end
|
||||
|
||||
### 獲取右子節點的索引 ###
|
||||
def right(i)
|
||||
2 * i + 2
|
||||
end
|
||||
|
||||
### 獲取父節點的索引 ###
|
||||
def parent(i)
|
||||
(i - 1) / 2 # 向下整除
|
||||
end
|
||||
|
||||
### 交換元素 ###
|
||||
def swap(i, j)
|
||||
@max_heap[i], @max_heap[j] = @max_heap[j], @max_heap[i]
|
||||
end
|
||||
|
||||
### 獲取堆積大小 ###
|
||||
def size
|
||||
@max_heap.length
|
||||
end
|
||||
|
||||
### 判斷堆積是否為空 ###
|
||||
def is_empty?
|
||||
size == 0
|
||||
end
|
||||
|
||||
### 訪問堆積頂元素 ###
|
||||
def peek
|
||||
@max_heap[0]
|
||||
end
|
||||
|
||||
### 元素入堆積 ###
|
||||
def push(val)
|
||||
# 新增節點
|
||||
@max_heap << val
|
||||
# 從底至頂堆積化
|
||||
sift_up(size - 1)
|
||||
end
|
||||
|
||||
### 從節點 i 開始,從底至頂堆積化 ###
|
||||
def sift_up(i)
|
||||
loop do
|
||||
# 獲取節點 i 的父節點
|
||||
p = parent(i)
|
||||
# 當“越過根節點”或“節點無須修復”時,結束堆積化
|
||||
break if p < 0 || @max_heap[i] <= @max_heap[p]
|
||||
# 交換兩節點
|
||||
swap(i, p)
|
||||
# 迴圈向上堆積化
|
||||
i = p
|
||||
end
|
||||
end
|
||||
|
||||
### 元素出堆積 ###
|
||||
def pop
|
||||
# 判空處理
|
||||
raise IndexError, "堆積為空" if is_empty?
|
||||
# 交換根節點與最右葉節點(交換首元素與尾元素)
|
||||
swap(0, size - 1)
|
||||
# 刪除節點
|
||||
val = @max_heap.pop
|
||||
# 從頂至底堆積化
|
||||
sift_down(0)
|
||||
# 返回堆積頂元素
|
||||
val
|
||||
end
|
||||
|
||||
### 從節點 i 開始,從頂至底堆積化 ###
|
||||
def sift_down(i)
|
||||
loop do
|
||||
# 判斷節點 i, l, r 中值最大的節點,記為 ma
|
||||
l, r, ma = left(i), right(i), i
|
||||
ma = l if l < size && @max_heap[l] > @max_heap[ma]
|
||||
ma = r if r < size && @max_heap[r] > @max_heap[ma]
|
||||
|
||||
# 若節點 i 最大或索引 l, r 越界,則無須繼續堆積化,跳出
|
||||
break if ma == i
|
||||
|
||||
# 交換兩節點
|
||||
swap(i, ma)
|
||||
# 迴圈向下堆積化
|
||||
i = ma
|
||||
end
|
||||
end
|
||||
|
||||
### 列印堆積(二元樹)###
|
||||
def __print__
|
||||
print_heap(@max_heap)
|
||||
end
|
||||
end
|
||||
|
||||
### Driver Code ###
|
||||
if __FILE__ == $0
|
||||
# 初始化大頂堆積
|
||||
max_heap = MaxHeap.new([9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2])
|
||||
puts "\n輸入串列並建堆積後"
|
||||
max_heap.__print__
|
||||
|
||||
# 獲取堆積頂元素
|
||||
peek = max_heap.peek
|
||||
puts "\n堆積頂元素為 #{peek}"
|
||||
|
||||
# 元素入堆積
|
||||
val = 7
|
||||
max_heap.push(val)
|
||||
puts "\n元素 #{val} 入堆積後"
|
||||
max_heap.__print__
|
||||
|
||||
# 堆積頂元素出堆積
|
||||
peek = max_heap.pop
|
||||
puts "\n堆積頂元素 #{peek} 出堆積後"
|
||||
max_heap.__print__
|
||||
|
||||
# 獲取堆積大小
|
||||
size = max_heap.size
|
||||
puts "\n堆積元素數量為 #{size}"
|
||||
|
||||
# 判斷堆積是否為空
|
||||
is_empty = max_heap.is_empty?
|
||||
puts "\n堆積是否為空 #{is_empty}"
|
||||
end
|
@ -0,0 +1,64 @@
|
||||
=begin
|
||||
File: top_k.rb
|
||||
Created Time: 2024-04-19
|
||||
Author: Blue Bean (lonnnnnnner@gmail.com)
|
||||
=end
|
||||
|
||||
require_relative "./my_heap"
|
||||
|
||||
### 元素入堆積 ###
|
||||
def push_min_heap(heap, val)
|
||||
# 元素取反
|
||||
heap.push(-val)
|
||||
end
|
||||
|
||||
### 元素出堆積 ###
|
||||
def pop_min_heap(heap)
|
||||
# 元素取反
|
||||
-heap.pop
|
||||
end
|
||||
|
||||
### 訪問堆積頂元素 ###
|
||||
def peek_min_heap(heap)
|
||||
# 元素取反
|
||||
-heap.peek
|
||||
end
|
||||
|
||||
### 取出堆積中元素 ###
|
||||
def get_min_heap(heap)
|
||||
# 將堆積中所有元素取反
|
||||
heap.max_heap.map { |x| -x }
|
||||
end
|
||||
|
||||
### 基於堆積查詢陣列中最大的 k 個元素 ###
|
||||
def top_k_heap(nums, k)
|
||||
# 初始化小頂堆積
|
||||
# 請注意:我們將堆積中所有元素取反,從而用大頂堆積來模擬小頂堆積
|
||||
max_heap = MaxHeap.new([])
|
||||
|
||||
# 將陣列的前 k 個元素入堆積
|
||||
for i in 0...k
|
||||
push_min_heap(max_heap, nums[i])
|
||||
end
|
||||
|
||||
# 從第 k+1 個元素開始,保持堆積的長度為 k
|
||||
for i in k...nums.length
|
||||
# 若當前元素大於堆積頂元素,則將堆積頂元素出堆積、當前元素入堆積
|
||||
if nums[i] > peek_min_heap(max_heap)
|
||||
pop_min_heap(max_heap)
|
||||
push_min_heap(max_heap, nums[i])
|
||||
end
|
||||
end
|
||||
|
||||
get_min_heap(max_heap)
|
||||
end
|
||||
|
||||
### Driver Code ###
|
||||
if __FILE__ == $0
|
||||
nums = [1, 7, 6, 3, 2]
|
||||
k = 3
|
||||
|
||||
res = top_k_heap(nums, k)
|
||||
puts "最大的 #{k} 個元素為"
|
||||
print_heap(res)
|
||||
end
|
@ -0,0 +1,24 @@
|
||||
=begin
|
||||
File: vertex.rb
|
||||
Created Time: 2024-04-25
|
||||
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
|
||||
=end
|
||||
|
||||
### 頂點類別 ###
|
||||
class Vertex
|
||||
attr_accessor :val
|
||||
|
||||
def initialize(val)
|
||||
@val = val
|
||||
end
|
||||
end
|
||||
|
||||
### 輸入值串列 vals ,返回頂點串列 vets ###
|
||||
def vals_to_vets(vals)
|
||||
Array.new(vals.length) { |i| Vertex.new(vals[i]) }
|
||||
end
|
||||
|
||||
### 輸入頂點串列 vets, 返回值串列 vals ###
|
||||
def vets_to_vals(vets)
|
||||
Array.new(vets.length) { |i| vets[i].val }
|
||||
end
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |