WideStudio Programming (2-5)~辞書順ソートと検索について

辞書順というのは言語によって違うのですが、タンゴレンで実装されているのは実際にはエスペラント(字上符を除くと英語)風の辞書順です。多くの場合はこれで充分だろうということで、現状では固定的に扱っています。

大文字・小文字・字上符に関して、ICUのUCollatorクラスを利用した比較関数を含むクラス(CALCollator)を作成することで、実現しています。関数名が“less_なんとか”となっているのは、std::lower_bound()/std::upper_bound()をインデックステーブル(std::vectorで実装)に対して適用出来るようにするためです。

class CALCollator {
public:
    struct CompOption {
        bool	m_ignore_case;
	.....
    };
private:
    UCollator 		*m_ucollator;
    UErrorCode		m_error_code;
    std::vector      m_options;
public:
    CALCollator();
    virtual ~CALCollator();

    bool Open(const char *locale_name="ja");
    void Close();
    UErrorCode	GetLastUErrorCode() const;

    bool less_exact_dictionary( const u16_string& str1, const u16_string& str2 );
    bool less_exact_forward( const u16_string& str1, const u16_string& str2 );
    bool less_exact_backward( const u16_string& str1, const u16_string& str2 );
    bool less_forward( const u16_string& str1, const u16_string& str2 );
    bool less_backward( const u16_string& str1, const u16_string& str2 );
    bool match_partial(const u16_string& str1, const u16_string& str2);

private:
    bool uchar_is_equal( const u16_string& str1, size_t from1,
                         const u16_string& str2, size_t from2);
    bool uchar_is_less( const u16_string& str1, size_t from1,
                        const u16_string& str2, size_t from2);

    void Clear();
    void Destroy();
};

色々あって、文字列の比較は結局一文字単位で行なうようになっています(例えば、less_exact_backword()は後ろから一文字ずつ切り出して、uchar_is_equal()とuchar_is_less()に渡しています)。文字列としてICUに比較させてしまうと、設定条件によって例えばハイフンが入っていてもいなくても同じ単語と見なされてしまったりして、具合が悪いからです。