新增了一行内容。
整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp
查找更方便的版本见:https://alg4.ikesnowy.com/
这一节内容可能会用到的库文件有 SymbolTable,同样在 Github 上可以找到。
善用 Ctrl + F 查找题目。
习题&题解
3.1.1
解答
官方解答:https://algs4.cs.princeton.edu/31elementary/GPA.java.html
ST.java:https://algs4.cs.princeton.edu/code/edu/princeton/cs/algs4/ST.java.html
建立一个符号表,然后把键值放进去,读取计算即可。
和上一章节用过的方法类似,先定义了一个接口 IST ,包含书中提到的基本 API。
然后定义类 ST ,用标准库里面的 Dictionary 实现了 IST 。
代码
using System.Collections; using System.Collections.Generic; namespace SymbolTable { ///利用库函数实现的标准符号表。public class ST: IST, IEnumerable{ private Dictionaryst; ///新建一个符号表。public ST() => this.st = new Dictionary(); ///检查符号表中是否存在与键对应的值。public virtual bool Contains(Key key) => this.st.ContainsKey(key); ///从符号表中删除键及对应的值。public virtual void Delete(Key key) => this.st.Remove(key); ///获取键对应的值,不存在时返回 null。public virtual Value Get(Key key) => this.st[key]; ///获取枚举器。public IEnumeratorGetEnumerator() => this.st.Keys.GetEnumerator(); ///检查符号表是否为空。public virtual bool IsEmpty() => this.st.Count == 0; ///获得符号表中所有键的集合。public virtual IEnumerableKeys() => this.st.Keys; ///向符号表中插入新的键值对。public virtual void Put(Key key, Value value) => this.st.Add(key, value); ///获取符号表中键值对的数量。public virtual int Size() => this.st.Count; ///获取枚举器。IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }
另请参阅
SymbolTable 库
3.1.2
解答
官方解答:https://algs4.cs.princeton.edu/31elementary/ArrayST.java.html
建立两个数组,分别存放键和值,一一对应。
添加时直接将新键值对放到数组最后即可。
删除时将待删除的键值对和位于最后的键值对交换,然后将其置空即可。
代码
using System; using System.Collections.Generic; namespace SymbolTable { ////// 符号表(数组实现)。 //////键类型。///值类型。public class ArrayST: IST{ private Key[] keys; // 键数组 private Value[] values; // 值数组 private int n = 0; // 键值对数目 ////// 建立基于数组实现的符号表。 ///public ArrayST() : this(8) { } ////// 建立基于数组实现的符号表。 //////初始大小。public ArrayST(int initCapacity) { this.keys = new Key[initCapacity]; this.values = new Value[initCapacity]; } ////// 检查键是否存在。 //////需要检查是否存在的键。///public bool Contains(Key key) => Get(key).Equals(default(Key)); ////// 删除键及对应的值。 //////需要删除的键。public void Delete(Key key) { for (int i = 0; i < this.n; i++) { if (key.Equals(this.keys[i])) { this.keys[i] = this.keys[this.n - 1]; this.values[i] = this.values[this.n - 1]; this.keys[this.n - 1] = default(Key); this.values[this.n - 1] = default(Value); this.n--; if (this.n > 0 && this.n == this.keys.Length / 4) Resize(this.keys.Length / 2); return; } } } ////// 获取键对应的值,若键不存在则返回 null。 //////需要查找的键。///public Value Get(Key key) { for (int i = 0; i < this.n; i++) if (this.keys[i].Equals(key)) return this.values[i]; return default(Value); } ////// 检查符号表是否为空。 //////public bool IsEmpty() => this.n == 0; ////// 获得包含全部键的集合。 //////public IEnumerableKeys() { Key[] result = new Key[this.n]; Array.Copy(this.keys, result, this.n); return result; } ////// 向符号表中插入新元素,若键存在将被替换。 //////键。///值。public void Put(Key key, Value value) { Delete(key); if (this.n >= this.values.Length) Resize(this.n * 2); this.keys[this.n] = key; this.values[this.n] = value; this.n++; } ////// 返回符号表中键值对的数量。 //////键值对数量。public int Size() => this.n; ////// 为符号表重新分配空间。 //////新分配的空间大小。private void Resize(int capacity) { Key[] tempKey = new Key[capacity]; Value[] tempValue = new Value[capacity]; for (int i = 0; i < this.n; i++) tempKey[i] = this.keys[i]; for (int i = 0; i < this.n; i++) tempValue[i] = this.values[i]; this.keys = tempKey; this.values = tempValue; } } }