Покритикуйте код hash_string ' a
От: dip_2000 Россия  
Дата: 22.08.07 07:36
Оценка:
Собственно задача понятна — получить класс который ведет себя "как basic_string"(при этом полный функционал вовсе не обязательно, отсюда отсутствие многого из интерфейса basic_string ), и в то же время сравнение объекто этого класса происходит через хэш). Смысла пинать функцию makeHash() особого нет( Её код тиснут из STL порта).
Основной критерйи по сути — возможность хранить в контейнерах STL.
template <class stringT>
class basic_hash_string
{        
public:    
    typedef typename stringT::value_type value_type;
    typedef typename stringT::size_type size_type;
    typedef size_type hash_type;

    void clear()
    {
        m_str.clear();
        m_Hash = 0;        
    }
    const size_type length() const
    {
        return m_str.length();
    }
    const hash_type getHash() const
    {
        return m_Hash;
    }
    basic_hash_string(const stringT& str)
    {
        assign( str.c_str() );
    }
    basic_hash_string(const value_type* value_type_str)
    {
        assign( value_type_str );
    }
    basic_hash_string& operator=(const stringT& Val)
    {
        assign( Val.c_str() );
        return *this;
    }
    basic_hash_string& operator=(const value_type* value_type_str)
    {
        assign(value_type_str );
        return *this;
    }
    basic_hash_string& operator+(const basic_hash_string& Val)
    {
        append( (static_cast<stringT>(Val)).c_str() );
        return *this;
    }
    basic_hash_string& operator+(const stringT& Val)
    {
        append( Val.c_str() );
        return *this;                
    }
    basic_hash_string& operator+(const value_type* value_type_str)
    {
        append( value_type_str );
        return *this;
    }
    basic_hash_string& operator+=(const basic_hash_string& Val)
    {
        append( (static_cast<stringT>(Val)).c_str() );
        return *this;
    }
    basic_hash_string& operator+=(const stringT& Val)
    {
        append( Val.c_str() );
        return *this;                
    }
    basic_hash_string& operator+=(const value_type* value_type_str)
    {
        append( value_type_str );
        return *this;
    }
    operator stringT()
    {
        return m_str;
    }
    const typename stringT::value_type* c_str() const
    {
        return Val.c_str();
    }
    const bool operator ==(const stringT& Val) const
    {
        return isEqual( Val.c_str() );
    }
    const bool operator ==(const basic_hash_string& Val) const
    {
        return m_Hash == Val.getHash();
    }
    const bool operator ==(const value_type* value_type_str) const
    {
        return isEqual( value_type_str );
    }
    const bool operator !=(const stringT& Val) const
    {
        return !isEqual( Val.c_str() );
    }
    const bool operator !=(const basic_hash_string& Val) const
    {
        return m_Hash != Val.getHash();
    }
    const bool operator !=(const value_type* value_type_str) const
    {
        return !isEqual( value_type_str );
    }
private:
    hash_type m_Hash;
    stringT m_str;

    const hash_type makeHash(const value_type * value) const 
    {
        unsigned long h = 0; 

        for ( ; *value; ++value)
            h = 5*h + *value;   

        return hash_type(h);
    }
    const bool isEqual(const value_type* value_type_st) const 
    {
        return m_str == value_type_st; 
    }
    void assign(const value_type* value_type_str)
    {
        m_Hash = makeHash( value_type_str );
        m_str = value_type_str;
    }
    void append( const value_type* value_type_str )
    {
        m_str.append( value_type_str );
        m_Hash = makeHash( value_type_str );        
    }
};
//пример использования
typedef basic_hash_string<string> hash_string;

string str1("123"), str2("321");
    int i = 0;

    hash_string HS1(str1), HS2("2"), HS3 = HS1;
    if (HS2 == HS1)
        i++;

    if ( HS3 == str1 )
        i--;

    if (HS2 == "2")
        i++;
    if (HS2 != "4")
        i++;

    HS1 += str1;
    HS1 += "312";
    HS2 =  HS1 + str2 ;

Re: Покритикуйте код hash_string ' a
От: COFF  
Дата: 22.08.07 09:04
Оценка:
Так как нет гарантии, что две разные строки всегда будут иметь разное значение хэша, то все-равно надо при равенстве хэшей двух строк проверять обычным способом — через strcmp или что-то подобное. Ну и я бы еще сделал вычисление хэша отложенным, при первом сравнении. А так получается, что на любой чих мы вычисляем хэш, даже если он нам потом и не понадобится. Вообще же, за исключением уж совсем клинических случаев, можно было бы хэш не хранить и сравнивать длину и первый/последний символ, например, чтобы быстро отсечь неравевенство.
Re: Покритикуйте код hash_string ' a
От: Vain Россия google.ru
Дата: 23.08.07 00:05
Оценка:
Здравствуйте, dip_2000, Вы писали:

_>Собственно задача понятна — получить класс который ведет себя "как basic_string"(при этом полный функционал вовсе не обязательно, отсюда отсутствие многого из интерфейса basic_string ), и в то же время сравнение объекто этого класса происходит через хэш). Смысла пинать функцию makeHash() особого нет( Её код тиснут из STL порта).

Я сначало подумал про HashTable со стрингом, тогда уж hashed_string, что бы не было путаницы.
Потом, ты можешь увеличить уникальность хеша, учитывая, что он будет сравниваться после сравнения длин строк.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Покритикуйте код hash_string ' a
От: dip_2000 Россия  
Дата: 23.08.07 04:02
Оценка:
COF>Так как нет гарантии, что две разные строки всегда будут иметь разное значение хэша, то все-равно надо при равенстве хэшей двух строк проверять обычным способом — через strcmp или что-то подобное. Ну и я бы еще сделал вычисление хэша отложенным, при первом сравнении. А так получается, что на любой чих мы вычисляем хэш, даже если он нам потом и не понадобится. Вообще же, за исключением уж совсем клинических случаев, можно было бы хэш не хранить и сравнивать длину и первый/последний символ, например, чтобы быстро отсечь неравевенство.
Спасибо за ответ, учту.
Re[2]: Покритикуйте код hash_string ' a
От: dip_2000 Россия  
Дата: 23.08.07 04:03
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, dip_2000, Вы писали:


_>>Собственно задача понятна — получить класс который ведет себя "как basic_string"(при этом полный функционал вовсе не обязательно, отсюда отсутствие многого из интерфейса basic_string ), и в то же время сравнение объекто этого класса происходит через хэш). Смысла пинать функцию makeHash() особого нет( Её код тиснут из STL порта).

V>Я сначало подумал про HashTable со стрингом,
угу, только не стандартен он по этому этот код и пишется...

> тогда уж hashed_string, что бы не было путаницы.

V>Потом, ты можешь увеличить уникальность хеша, учитывая, что он будет сравниваться после сравнения длин строк.
Спасибо, учту.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.