⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dictionary.zc

📁 实现树形结构
💻 ZC
字号:
//[of]:description
//[c]The hashtable class
//[c]
//[c]Abstract class for dictionaries. The class must be inherited to be used.
//[c]Implement the following methods:	
//[c]- hash ()   returns the hash code of a key	
//[c]- match ()  compare two keys
//[cf]
//[of]:imports
import "base/types"
import "base/numbers"
import "base/memory"
import "base/memory-allocator"
//[cf]
//[of]:types
//[c]
public typedef key = -> void
public typedef value = -> void
//[cf]
//[of]:structures
//[c]
private struct association
	key: key
	value: value
end
//[c]
public struct dictionary class
	hash: {key} int
	is equal: {key, key} bool
end
//[c]
//[c]
//[c]Instance variables:
//[c]
//[c]	associations
//[c]		buffer to all associations
//[c]	size
//[c]		total number of slots
//[c]	tally
//[c]		number of used slots
//[c]	collisions
//[c]		maximum of collisions occured
//[c]
//[c]collisions is an upper bound: after removing an association the
//[c]value may be wrong
//[c]
public struct dictionary

	private class: dictionary class
	private associations: [] local association
	private tally: size
	private allocated: size
	private collisions: int

end
//[cf]
//[c]
//[of]:initialize - release
//[of]:dictionary (class)
//[c]Initializes a new hastable
//[c]
public equ dictionary (class: dictionary class, d: dictionary) = initialize (d, class)
//[cf]
//[c]
//[of]:initialize (d, class)
//[c]
public func initialize (d: dictionary, class: dictionary class)

	class (d) = class
	collisions (d) = 0
	tally (d) = 0:d
	allocated (d) = default allocated
	associations (d) = new array of associations (default allocated)
	
	each (associations (d), default allocated) ? a
		key (a) = nil
	end

end
//[cf]
//[of]:release (d)
//[c]Deletes an hashtable
//[c]
public func release (d: dictionary)

	// it is the responsibility of the sub-class to free the keys and values
	free memory (associations(d))

end
//[cf]
//[cf]
//[of]:adding - removing
//[of]:add (d, key, value)
//[c]Puts value
//[c]
//[c]There must be at least one free slot.
//[c]If there were already a value at this slot, the old value is returned.
//[c]In such a case, the returned value, and the passed key are no more
//[c]referenced by the dictionary, it is the responsibility of the sub-class
//[c]to free them.
//[c]
public func add(d: dictionary, k: key, v: value)

	def location = slot (d, k)
	def count = 1
	
	repeat
		def a = associations(d)[location]
		if not empty (a)
			if is equal (d, k, key (a))
				def old = value (a)
				value (a) = v
				return old
			else
				circular inc (location, allocated (d))
				++count
			end
		else
			key (a) = k
			value (a) = v
			if count > collisions (d)
				collisions (d) = count
			end
			increase tally (d)
			return nil
		end
	end
	
	return nil // make compiler happy

end
//[cf]
//[of]:remove (d, key)
//[c]Removes an item
//[c]
//[c]Returns the item for the given key or nil if not found
//[c]
public func remove (d: dictionary, k: key)

	def location = slot (d, k)
	def count = collisions (d)

	while count > 0 && not empty (d, location)
		def a = associations(d)[location]
		if is equal (d, k, key (a))
			clear (a)
			circular inc (location, allocated (d))
			fill up (d, location) // useless if we are going to resize
			decrease tally (d)
			return
		end
		circular inc (location, allocated (d))
		--count
	end
	
end
//[cf]
//[cf]
//[of]:enumerating
//[of]:each key and value (d)
//[c]Enumerates keys and values
//[c]
public equ each key and value (d: dictionary)

	def i = 0:d
	def size = allocated (d)
	while i < size
		if not empty (d, i)
			def a = associations(d)[i]
			yield (key (a), value (a))
		end
		++i
	end

end
//[cf]
//[of]:each key (d)
//[c]Enumerates keys
//[c]
public equ each key (d: dictionary)

	def i = 0:d
	def size = allocated (d)
	while i<size
		if not empty(d, i)
			def v = key (associations(d)[i])
			yield (v)
		end
		++i
	end

end
//[cf]
//[of]:each value (d)
//[c]Enumerates values
//[c]
public equ each value (d: dictionary)

	def i = 0:d
	def size = allocated (d)
	while i<size
		if not empty(d, i)
			def v = value (associations(d)[i])
			yield (v)
		end
		++i
	end

end
//[cf]
//[cf]
//[of]:accessing
//[of]:size (d)
//[c]
public equ size (d: dictionary) = 
	tally (d)
//[cf]
//[of]:value (d, key)
//[c]Finds value
//[c]
//[c]	Returns the value for the given key
//[c]
public func value (d: dictionary, k: key)

	def location = slot (d, k)
	def count = collisions (d)
	
	while count>0 && not empty (d, location)
		def a = associations (d) [location]
		if is equal (d, key (a), k)
			return value (a)
		end
		circular inc (location, allocated (d))
		--count
	end
	
	return nil

end
//[cf]
//[of]:d [key]
//[c]
public equ @at (d: dictionary, k: key) = value (d, k)
//[cf]
//[cf]
//[of]:testing
//[of]:is empty (d)
//[c]
public equ is empty (d: dictionary) = 
	tally (d) == 0:d
//[cf]
//[of]:not empty (d)
//[c]
public equ not empty (d: dictionary) = 
	tally (d) <> 0:d
//[cf]
//[cf]
//[c]
//[of]:private
//[c]private
//[c]
//[of]:constants
//[c]
equ default allocated = 10
//[cf]
//[c]
//[of]:resize (d, size)
//[c]Resizes the list of associations
//[c]
func resize (d: dictionary, s: size)

	def c = 0
	def a = new array of associations (s)
	
	each (a, s) ? e
		key(e) = nil
	end

	each key and value (d) ? key, value
	
		def count = 1
		def location = hash (d, key):dword % s
		while not nil (a[location].key)
			circular inc (location, s)
			++ count
		end
		
		key (a[location]) = key
		value (a[location]) = value
		c = max(count, c)
	
	end
	
	free memory (associations (d))
	collisions (d) = c
	associations (d) = a
	allocated (d) = s

end
//[cf]
//[of]:increase tally (d)
//[c]Increases the counter of items
//[c]Grow the array if more than 75% of slots are used
//[c]
func increase tally (d: dictionary)

	++ tally (d)
	if 4 * tally (d) > 3 * allocated (d)
		resize (d, allocated (d) * 3 / 2)
	end

end
//[cf]
//[of]:decrease tally (d)
//[c]Decreases the counter of items
//[c]Reduce the array if less than 30% of slots are used
//[c]
func decrease tally (d: dictionary)

	++tally (d)
	if 3 * tally (d) < allocated (d)
		resize (d, max (default allocated, 2 * allocated (d) / 3))
	end

end
//[cf]
//[of]:fill up (d, current)
//[c]Fixes collisions after freeing a slot
//[c]
func fill up (d: dictionary, current: dword)

	while not empty (d, current)
		def best = slot (d, key (d, current))
		def count = 0
		if current <> best
			while not empty (d, best)
				circular inc (best, allocated (d))
				++count
			end
		end
		if current <> best
			copy (associations(d)[best], associations(d)[current])
			clear (d, current)
			collisions (d) = max (collisions (d), count)
		end
		circular inc (current, allocated (d))
	end

end
//[cf]
//[c]
//[of]:key (d, index)
//[c]
equ key (d: dictionary, i: dword) = 
	key (associations(d) [i])
//[cf]
//[of]:value (d, index)
//[c]
equ value (d: dictionary, i: dword) = 
	value (associations (d) [i])
//[cf]
//[of]:is empty (d, index)
//[c]
equ is empty (d: dictionary, i: dword) = 
	is nil (key (associations(d) [i]))
//[cf]
//[of]:not empty (d, index)
//[c]
equ not empty (d: dictionary, i: dword) = 
	not nil (key (associations(d) [i]))
//[cf]
//[of]:set key (d, index, key)
//[c]
equ set key (d: dictionary, i: dword, k: key) = 
	key (associations(d) [i]) = k
//[cf]
//[of]:set value (d, index, value)
//[c]
equ set value (d: dictionary, i: dword, v: value) = 
	value (associations(d) [i]) = v
//[cf]
//[of]:clear (d, index)
//[c]
equ clear (d: dictionary, i: dword) = 
	set key (d, i, nil)
//[cf]
//[c]
//[of]:hash (d, key)
//[c]
equ hash (d: dictionary, k: key) = 
	hash (class (d)) {k}
//[cf]
//[of]:is equal (d, key1, key2)
//[c]
equ is equal (d: dictionary, k1: key, k2: key) = 
	is equal (class (d)) {k1, k2}
//[cf]
//[of]:slot (d, key)
//[c]
equ slot (d: dictionary, k:key) = 
	hash (d, k) : dword % allocated (d)
//[cf]
//[c]
//[c]association
//[of]:is empty (a)
//[c]
equ is empty (a: association) = is nil (key (a))
//[cf]
//[of]:not empty (a)
//[c]
equ not empty (a: association) = not nil (key (a))
//[cf]
//[of]:clear (a)
//[c]
equ clear (a: association) = key (a) = nil
//[cf]
//[of]:each ([] local association, size)
//[c]
equ each (a: [] local association, s: size)

	def i = 0:d
	while i < s
		yield (a[i])
		++i
	end

end
//[cf]
//[of]:copy (src)
//[c]
equ copy (dst: association, src: association)
	key (dst) = key (src)
	value (dst) = value (src)
end
//[cf]
//[of]:new array of associations (size)
//[c]
equ new array of associations (s: size) =  
	
	allocate memory (s * sizeof local association) : [] local association

//[cf]
//[c]
//[c]integer
//[of]:circular inc (x, size)
//[c]
equ circular inc (x: dword, s: size)

	++x
	if x==s
		x = 0
	end

end
//[cf]
//[cf]

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -