Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Ruby code - chapter "Hashing" #1276

Merged
merged 3 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions codes/ruby/chapter_hashing/array_hash_map.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
=begin
File: array_hash_map.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end

### 键值对 ###
class Pair
attr_accessor :key, :val

def initialize(key, val)
@key = key
@val = val
end
end

### 基于数组实现的哈希表 ###
class ArrayHashMap
### 构造方法 ###
def initialize
khoaxuantu marked this conversation as resolved.
Show resolved Hide resolved
# 初始化数组,包含 100 个桶
@buckets = Array.new(100)
end

### 哈希函数 ###
def hash_func(key)
index = key % 100
end

### 查询操作 ###
def get(key)
index = hash_func(key)
pair = @buckets[index]

return if pair.nil?
pair.val
end

### 添加操作 ###
def put(key, val)
pair = Pair.new(key, val)
index = hash_func(key)
@buckets[index] = pair
end

### 删除操作 ###
def remove(key)
index = hash_func(key)
# 置为 nil ,代表删除
@buckets[index] = nil
end

### 获取所有键值对 ###
def entry_set
result = []
@buckets.each { |pair| result << pair unless pair.nil? }
result
end

### 获取所有键 ###
def key_set
result = []
@buckets.each { |pair| result << pair.key unless pair.nil? }
result
end

### 获取所有值 ###
def value_set
result = []
@buckets.each { |pair| result << pair.val unless pair.nil? }
result
end

### 打印哈希表 ###
def print
@buckets.each { |pair| puts "#{pair.key} -> #{pair.val}" unless pair.nil? }
end
end

### Driver Code ###
if __FILE__ == $0
# 初始化哈希表
hmap = ArrayHashMap.new

# 添加操作
# 在哈希表中添加键值对 (key, value)
hmap.put(12836, "小哈")
hmap.put(15937, "小啰")
hmap.put(16750, "小算")
hmap.put(13276, "小法")
hmap.put(10583, "小鸭")
puts "\n添加完成后,哈希表为\nKey -> Value"
hmap.print

# 查询操作
# 向哈希表中输入键 key , 得到值 value
name = hmap.get(15937)
puts "\n输入学号 15937 ,查询到姓名 #{name}"

# 删除操作
# 在哈希表中删除值对 (key, value)
hmap.remove(10583)
puts "\n删除 10583 后,哈希表为\nKey -> Value"
hmap.print

# 遍历哈希表
puts "\n遍历键值对 Key->Value"
for pair in hmap.entry_set
puts "#{pair.key} -> #{pair.val}"
end

puts "\n单独篇遍历键 Key"
for key in hmap.key_set
puts key
end

puts "\n单独遍历值 Value"
for val in hmap.value_set
puts val
end
end
34 changes: 34 additions & 0 deletions codes/ruby/chapter_hashing/built_in_hash.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
=begin
File: built_in_hash.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end

require_relative '../utils/list_node'

### Driver Code ###
if __FILE__ == $0
num = 3
hash_num = num.hash
puts "整数 #{num} 的哈希值为 #{hash_num}"

bol = true
hash_bol = bol.hash
puts "布尔量 #{bol} 的哈希值为 #{hash_bol}"

dec = 3.14159
hash_dec = dec.hash
puts "小数 #{dec} 的哈希值为 #{hash_dec}"

str = "Hello 算法"
hash_str = str.hash
puts "字符串 #{str} 的哈希值为 #{hash_str}"

tup = [12836, '小哈']
hash_tup = tup.hash
puts "元组 #{tup} 的哈希值为 #{hash_tup}"

obj = ListNode.new(0)
hash_obj = obj.hash
puts "节点对象 #{obj} 的哈希值为 #{hash_obj}"
end
44 changes: 44 additions & 0 deletions codes/ruby/chapter_hashing/hash_map.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
=begin
File: hash_map.rb
Created Time: 2024-04-14
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end

require_relative '../utils/print_util'

### Driver Code ###
if __FILE__ == $0
# 初始化哈希表
hmap = {}

# 添加操作
# 在哈希表中添加键值对 (key, value)
hmap[12836] = "小哈"
hmap[15937] = "小啰"
hmap[16750] = "小算"
hmap[13276] = "小法"
hmap[10583] = "小鸭"
puts "\n添加完成后,哈希表为\nKey -> Value"
print_hash_map(hmap)

# 查询操作
# 向哈希表中输入键 key ,得到值 value
name = hmap[15937]
puts "\n输入学号 15937 ,查询到姓名 #{name}"

# 删除操作
# 在哈希表中删除键值对 (key, value)
hmap.delete(10583)
puts "\n删除 10583 后,哈希表为\nKey -> Value"
print_hash_map(hmap)

# 遍历哈希表
puts "\n遍历键值对 Key->Value"
hmap.entries.each { |key, value| puts "#{key} -> #{value}" }

puts "\n单独遍历键 Key"
hmap.keys.each { |key| puts key }

puts "\n单独遍历值 Value"
hmap.values.each { |val| puts val }
end
128 changes: 128 additions & 0 deletions codes/ruby/chapter_hashing/hash_map_chaining.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
=begin
File: hash_map_chaining.rb
Created Time: 2024-04-13
Author: Xuan Khoa Tu Nguyen (ngxktuzkai2000@gmail.com)
=end

require_relative './array_hash_map'

### 键式地址哈希表 ###
class HashMapChaining
### 构造方法 ###
def initialize
@size = 0 # 键值对数量
@capacity = 4 # 哈希表容量
@load_thres = 2.0 / 3.0 # 触发扩容的负载因子阈值
@extend_ratio = 2 # 扩容倍数
@buckets = Array.new(@capacity) { [] } # 桶数组
end

### 哈希函数 ###
def hash_func(key)
key % @capacity
end

### 负载因子 ###
def load_factor
@size / @capacity
end

### 查询操作 ###
def get(key)
index = hash_func(key)
bucket = @buckets[index]
# 遍历桶,若找到 key ,则返回对应 val
for pair in bucket
return pair.val if pair.key == key
end
# 若未找到 key , 则返回 nil
nil
end

### 添加操作 ###
def put(key, val)
# 当负载因子超过阈值时,执行扩容
extend if load_factor > @load_thres
index = hash_func(key)
bucket = @buckets[index]
# 遍历桶,若遇到指定 key ,则更新对应 val 并返回
for pair in bucket
if pair.key == key
pair.val = val
return
end
end
# 若无该 key ,则将键值对添加至尾部
pair = Pair.new(key, val)
bucket << pair
@size += 1
end

### 删除操作 ###
def remove(key)
index = hash_func(key)
bucket = @buckets[index]
# 遍历桶,从中删除键值对
for pair in bucket
if pair.key == key
bucket.delete(pair)
@size -= 1
break
end
end
end

### 扩容哈希表 ###
def extend
# 暫存原哈希表
buckets = @buckets
# 初始化扩容后的新哈希表
@capacity *= @extend_ratio
@buckets = Array.new(@capacity) { [] }
@size = 0
# 将键值对从原哈希表搬运至新哈希表
for bucket in buckets
for pair in bucket
put(pair.key, pair.val)
end
end
end

### 打印哈希表 ###
def print
for bucket in @buckets
res = []
for pair in bucket
res << "#{pair.key} -> #{pair.val}"
end
pp res
end
end
end

### Driver Code ###
if __FILE__ == $0
### 初始化哈希表
hashmap = HashMapChaining.new

# 添加操作
# 在哈希表中添加键值对 (key, value)
hashmap.put(12836, "小哈")
hashmap.put(15937, "小啰")
hashmap.put(16750, "小算")
hashmap.put(13276, "小法")
hashmap.put(10583, "小鸭")
puts "\n添加完成后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]"
hashmap.print

# 查询操作
# 向哈希表中输入键 key ,得到值 value
name = hashmap.get(13276)
puts "\n输入学号 13276 ,查询到姓名 #{name}"

# 删除操作
# 在哈希表中删除键值对 (key, value)
hashmap.remove(12836)
puts "\n删除 12836 后,哈希表为\n[Key1 -> Value1, Key2 -> Value2, ...]"
hashmap.print
end
Loading