3.1.2 #
解答 #
官方解答:https://algs4.cs.princeton.edu/31elementary/ArrayST.java.html
建立两个数组,分别存放键和值,一一对应。
添加时直接将新键值对放到数组最后即可。
删除时将待删除的键值对和位于最后的键值对交换,然后将其置空即可。
代码 #
public class ArraySt<TKey, TValue> : ISt<TKey, TValue>
{
/// <summary>
/// 键数组。
/// </summary>
/// <value>键数组。</value>
private TKey[] _keys;
/// <summary>
/// 值数组。
/// </summary>
/// <value>值数组。</value>
private TValue[] _values;
/// <summary>
/// 键值对数目。
/// </summary>
/// <value>键值对数目。</value>
private int _n;
/// <summary>
/// 建立基于数组实现的符号表。
/// </summary>
public ArraySt() : this(8) { }
/// <summary>
/// 建立基于数组实现的符号表。
/// </summary>
/// <param name="initCapacity">初始大小。</param>
public ArraySt(int initCapacity)
{
_keys = new TKey[initCapacity];
_values = new TValue[initCapacity];
}
/// <summary>
/// 检查键 <typeparamref name="TKey"/> 是否存在。
/// </summary>
/// <param name="key">需要检查是否存在的键。</param>
/// <returns>如果存在则返回 <c>true</c>,否则返回 <c>false</c>。</returns>
public bool Contains(TKey key) => Get(key).Equals(default(TKey));
/// <summary>
/// 删除键 <paramref name="key"/> 及对应的值。
/// </summary>
/// <param name="key">需要删除的键。</param>
public void Delete(TKey key)
{
for (var i = 0; i < _n; i++)
{
if (key.Equals(_keys[i]))
{
_keys[i] = _keys[_n - 1];
_values[i] = _values[_n - 1];
_keys[_n - 1] = default;
_values[_n - 1] = default;
_n--;
if (_n > 0 && _n == _keys.Length / 4)
Resize(_keys.Length / 2);
return;
}
}
}
/// <summary>
/// 获取键对应的值,若键不存在则返回 null。
/// </summary>
/// <param name="key">需要查找的键。</param>
/// <returns>找到的值,不存在则返回 <c>default(Value)</c></returns>
public TValue Get(TKey key)
{
for (var i = 0; i < _n; i++)
if (_keys[i].Equals(key))
return _values[i];
return default;
}
/// <summary>
/// 检查符号表是否为空。
/// </summary>
/// <returns>为空则返回 <c>true</c>,否则返回 <c>false</c>。</returns>
public bool IsEmpty() => _n == 0;
/// <summary>
/// 获得包含全部键的集合。
/// </summary>
/// <returns>全部键的集合。</returns>
public IEnumerable<TKey> Keys()
{
var result = new TKey[_n];
Array.Copy(_keys, result, _n);
return result;
}
/// <summary>
/// 向符号表中插入新元素,若键存在将被替换。
/// </summary>
/// <param name="key">键。</param>
/// <param name="value">值。</param>
public void Put(TKey key, TValue value)
{
Delete(key);
if (_n >= _values.Length)
Resize(_n * 2);
_keys[_n] = key;
_values[_n] = value;
_n++;
}
/// <summary>
/// 返回符号表中键值对的数量。
/// </summary>
/// <returns>键值对数量。</returns>
public int Size() => _n;
/// <summary>
/// 为符号表重新分配空间。
/// </summary>
/// <param name="capacity">新分配的空间大小。</param>
private void Resize(int capacity)
{
var tempKey = new TKey[capacity];
var tempValue = new TValue[capacity];
for (var i = 0; i < _n; i++)
tempKey[i] = _keys[i];
for (var i = 0; i < _n; i++)
tempValue[i] = _values[i];
_keys = tempKey;
_values = tempValue;
}
}