算法(第四版)C# 習題題解——3.1

寫在前面

新增了一行內容。
整個項目都託管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp
查找更方便的版本見:https://alg4.ikesnowy.com/
這一節內容可能會用到的庫文件有 SymbolTable,一樣在 Github 上能夠找到。
善用 Ctrl + F 查找題目。html

習題&題解

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.htmljava

創建一個符號表,而後把鍵值放進去,讀取計算便可。
和上一章節用過的方法相似,先定義了一個接口 IST<Key, Value> ,包含書中提到的基本 API。
而後定義類 ST ,用標準庫裏面的 Dictionary 實現了 ISTgit

代碼
using System.Collections;
using System.Collections.Generic;

namespace SymbolTable
{
    /// <summary> 利用庫函數實現的標準符號表。 </summary>
    public class ST<Key, Value> : IST<Key, Value>, IEnumerable<Key>
    {
        private Dictionary<Key, Value> st;

        /// <summary> 新建一個符號表。 </summary>
        public ST() => this.st = new Dictionary<Key, Value>();

        /// <summary> 檢查符號表中是否存在與鍵 <paramref name="key"/> 對應的值。 </summary>
        public virtual bool Contains(Key key) => this.st.ContainsKey(key);

        /// <summary> 從符號表中刪除鍵 <paramref name="key"/> 及對應的值。 </summary>
        public virtual void Delete(Key key) => this.st.Remove(key);

        /// <summary> 獲取鍵 <paramref name="key"/> 對應的值,不存在時返回 null。 </summary>
        public virtual Value Get(Key key) => this.st[key];

        /// <summary> 獲取枚舉器。 </summary>
        public IEnumerator<Key> GetEnumerator() => this.st.Keys.GetEnumerator();

        /// <summary> 檢查符號表是否爲空。 </summary>
        public virtual bool IsEmpty() => this.st.Count == 0;

        /// <summary> 得到符號表中全部鍵的集合。 </summary>
        public virtual IEnumerable<Key> Keys() => this.st.Keys;

        /// <summary> 向符號表中插入新的鍵值對。 </summary>
        public virtual void Put(Key key, Value value) => this.st.Add(key, value);

        /// <summary> 獲取符號表中鍵值對的數量。 </summary>
        public virtual int Size() => this.st.Count;

        /// <summary> 獲取枚舉器。 </summary>
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }
}
另請參閱

SymbolTable 庫github

3.1.2

解答

官方解答:https://algs4.cs.princeton.edu/31elementary/ArrayST.java.html數組

創建兩個數組,分別存放鍵和值,一一對應。
添加時直接將新鍵值對放到數組最後便可。
刪除時將待刪除的鍵值對和位於最後的鍵值對交換,而後將其置空便可。函數

代碼
using System;
using System.Collections.Generic;

namespace SymbolTable
{
    /// <summary>
    /// 符號表(數組實現)。
    /// </summary>
    /// <typeparam name="Key">鍵類型。</typeparam>
    /// <typeparam name="Value">值類型。</typeparam>
    public class ArrayST<Key, Value> : IST<Key, Value> 
    {
        private Key[] keys;             // 鍵數組
        private Value[] values;         // 值數組
        private int n = 0;              // 鍵值對數目

        /// <summary>
        /// 創建基於數組實現的符號表。
        /// </summary>
        public ArrayST() : this(8) { }

        /// <summary>
        /// 創建基於數組實現的符號表。
        /// </summary>
        /// <param name="initCapacity">初始大小。</param>
        public ArrayST(int initCapacity)
        {
            this.keys = new Key[initCapacity];
            this.values = new Value[initCapacity];
        }

        /// <summary>
        /// 檢查鍵 <typeparamref name="Key"/> 是否存在。
        /// </summary>
        /// <param name="key">須要檢查是否存在的鍵。</param>
        /// <returns></returns>
        public bool Contains(Key key) => Get(key).Equals(default(Key));

        /// <summary>
        /// 刪除鍵 <paramref name="key"/> 及對應的值。
        /// </summary>
        /// <param name="key">須要刪除的鍵。</param>
        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;
                }
            }
        }

        /// <summary>
        /// 獲取鍵對應的值,若鍵不存在則返回 null。
        /// </summary>
        /// <param name="key">須要查找的鍵。</param>
        /// <returns></returns>
        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);
        }

        /// <summary>
        /// 檢查符號表是否爲空。
        /// </summary>
        /// <returns></returns>
        public bool IsEmpty() => this.n == 0;

        /// <summary>
        /// 得到包含所有鍵的集合。
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Key> Keys()
        {
            Key[] result = new Key[this.n];
            Array.Copy(this.keys, result, this.n);
            return result;
        }

        /// <summary>
        /// 向符號表中插入新元素,若鍵存在將被替換。
        /// </summary>
        /// <param name="key">鍵。</param>
        /// <param name="value">值。</param>
        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++;
        }

        /// <summary>
        /// 返回符號表中鍵值對的數量。
        /// </summary>
        /// <returns>鍵值對數量。</returns>
        public int Size() => this.n;

        /// <summary>
        /// 爲符號表從新分配空間。
        /// </summary>
        /// <param name="capacity">新分配的空間大小。</param>
        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;
        }
    }
}
另請參閱

SymbolTable 庫工具

本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈this

相關文章
相關標籤/搜索