< 対数あれこれ | ローカルネットワークを選択するコンボボックス >

February 7, 2006

しょぼ Hash クラス

低機能な連想配列クラスです。お仕事プログラムで、キーと値を対にして格納するようなファイルを読み込む際に、値をパースする関数のポインタを格納するためにさらさらっと書いたものなので、動作確認は十分にしていません。キーや値の列挙等はサポートしていません。(そのうち気が向いたらつけるかもしれませんが)キーは文字列、しかも TCHAR [] のみの対応です。よく言えばシンプルで、メモリの消費量も小さいので、固定のディクショナリとしてなら使い道があるかもしれません。

CLightHash <int, -1> IntHash;
IntHash.Add ("abcde", 5);
IntHash.Add ("abc", 7);
IntHash.Add ("ac", 6);
int nRet;
nRet = IntHash.Explore ("abcde");
nRet = IntHash.Explore ("abcdef");
nRet = IntHash.Explore ("abc");
nRet = IntHash.Explore ("ac");
nRet = IntHash.Explore ("");

nRet = IntHash ["abcde"];
nRet = IntHash ["abcdef"];
nRet = IntHash ["abc"];
nRet = IntHash ["ac"];
nRet = IntHash [""];
IntHash ["123"] = 123;
nRet = IntHash ["123"];

# イマイチ汎用性に欠けているとはいえ、こういう流用可能なクラスを一所懸命作っているあたり、仕事がいまひとつ調子が出てないのがバレバレですな・・・。
# 調子がよければこんなの作ってませんとも 笑。

#ifndef __LIGHTHASH__H
#define __LIGHTHASH__H

// ノードの宣言
template <typename _ValType, _ValType vDefault = NULL>
class CLightHashNode
{
public:
    typedef CLightHashNode <_ValType, vDefault> _ThisType;
    
    // デフォルトコンストラクタ
    CLightHashNode (void)
        : m_chNode (0) , m_Val (vDefault)
        , m_pNextSibling (NULL) , m_pFirstChild (NULL)
    {
    }
    
    // デストラクタ
    virtual ~CLightHashNode (void)
    {
        delete m_pNextSibling;
        delete m_pFirstChild;
    }

    // 弟(妹)を返す
    _ThisType*  NextSibling (void)
    {
        return m_pNextSibling;
    }
    
    // 長男(長女)を返す
    _ThisType*  FirstChild (void)
    {
        return m_pFirstChild;
    }

    // ハッシュ値を追加
    // 重複は許していないため、既にキーがあればFALSEを返す
    BOOL Add (LPCTSTR lpszKey, const _ValType& Val)
    {
        BOOL bRet = FALSE;
        if (*lpszKey == m_chNode)
        {// 文字が同じ
            if (m_pFirstChild)
            {// 子がいる場合は追加できるかやってみる
                bRet = m_pFirstChild->Add (lpszKey + 1, Val);
            }
            else
            {// 自分が終端(ヌル文字)ならFALSE
                bRet = FALSE;
            }
        }
        else if (m_pNextSibling)
        {// 文字が異なるが、兄弟ありなら、兄弟に追加できるかやってみる
            bRet = m_pNextSibling->Add (lpszKey, Val);
        }
        else
        {// 末っ子なら、弟を追加する
            m_pNextSibling = new _ThisType (lpszKey, Val);
            if (m_pNextSibling)
            {// 追加成功
                bRet = TRUE;
            }
        }
        return bRet;
    }

    // ハッシュ値を検索
    const _ValType Explore (LPCTSTR lpszKey) const
    {
        _ValType    Val (vDefault);
        if (*lpszKey == m_chNode)
        {// 文字が同じ
            if (m_pFirstChild)
            {// 子がいれば子を検索
                return m_pFirstChild->Explore (lpszKey + 1);
            }
            else
            {// NULL文字
                return m_Val;
            }
        }
        else if (m_pNextSibling)
        {// 文字が異なるが、兄弟ありなら兄弟から探してみる
            return m_pNextSibling->Explore (lpszKey);
        }
        return Val;
    }
    
    _ValType& operator = (const _ValType& Val)
    {
        m_Val = Val;
        return m_Val;
    }

    operator _ValType (void)
    {
        return m_Val;
    }

    _ThisType& operator [] (LPCTSTR lpszKey)
    {
        if (*lpszKey == m_chNode)
        {// 文字が同じ
            if (m_pFirstChild)
            {// 子がいる場合
                return m_pFirstChild->operator [] (lpszKey + 1);
            }
            else
            {// 自分が終端
                return *this;
            }
        }
        else if (m_pNextSibling)
        {// 文字が異なるが、兄弟ありなら、兄弟にわたす
            return m_pNextSibling->operator [] (lpszKey);
        }

        // 末っ子なら、弟を追加する
        m_pNextSibling = new _ThisType (lpszKey, vDefault);
        return m_pNextSibling->operator [] (lpszKey);
    }

protected:
    TCHAR       m_chNode;       // 自身を表す文字
    _ValType    m_Val;          // 値
    _ThisType*  m_pNextSibling;
    _ThisType*  m_pFirstChild;

    // 兄弟コンストラクタ
    CLightHashNode (LPCTSTR lpszKey, _ValType Val)
        : m_chNode (*lpszKey) , m_Val (vDefault)
        , m_pNextSibling (NULL) , m_pFirstChild (NULL)
    {
        if (m_chNode)
        {// ヌル文字ではない
            m_pFirstChild = new _ThisType (lpszKey + 1, Val);
        }
        else
        {// ヌル文字なら、ここに値をセット
            m_Val = Val;
        }
    }

};


// ハッシュの宣言→今のところ、ノードと同じ
template <typename _ValType, _ValType vDefault = NULL>
class CLightHash
    : public CLightHashNode <_ValType,vDefault> 
{
};

#endif  //__LIGHTHASH__H

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/1269

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?