Подтвердить что ты не робот

Как я могу передать строку в int с помощью С++?

Мне нужно написать собственную хэш-функцию. Если бы я хотел просто сделать простую хеш-функцию, которая отображает каждую букву в строке на числовое значение (т.е. a = 1, b = 2, c = 3,...), есть способ, которым я могу выполнить этот хеш строка без необходимости сначала преобразовывать ее в c-строку, чтобы посмотреть на каждый отдельный char? Есть ли более эффективный способ хеширования строк?

4b9b3361

Ответ 1

Повторите первый вопрос, конечно, например:

int hash = 0;
int offset = 'a' - 1;
for(string::const_iterator it=s.begin(); it!=s.end(); ++it) {
  hash = hash << 1 | (*it - offset);
}

относительно второго, существует много лучших способов хэш-строк. Например, см. здесь для нескольких примеров C (легко переводимых на С++ по линиям вышеприведенного фрагмента).

Ответ 2

Из личного опыта я знаю, что это работает и создает хорошие распределения. (Плагиат из http://www.cse.yorku.ca/~oz/hash.html):

djb2

этот алгоритм (k = 33) впервые был дан Дан Бернштейном много лет назад в comp.lang.c. другая версия этого алгоритма (в настоящее время пользуется бернштейном) использует xor: hash (i) = hash (i - 1) * 33 ^ str [i]; магия числа 33 (почему она работает лучше, чем многие другие константы, простые или нет) никогда не была адекватно объяснена.

unsigned long hash(unsigned char *str) {
    unsigned long hash = 5381;
    int c;

    while (c = *str++) {
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    }

    return hash;
}

Ответ 3

Вы можете просмотреть каждый char из std::string с помощью оператора []. Тем не менее, вы можете посмотреть Boost:: Functional/Hash для руководства по лучшей схеме хэширования. Существует также список хэш-функций в c, расположенный здесь.

Ответ 4

Здесь C (++) хэш-функция, которую я нашел в книге Страуструпа:

int hash(const char *str)
{
    int h = 0;
    while (*str)
       h = h << 1 ^ *str++;
    return h;
}

Если вы используете его для хэш-таблицы (что делает Stroustrup), вы можете вместо этого вернуть абс хэш по модулю простого числа. Поэтому вместо

    return (h > 0 ? h : -h) % N_BUCKETS;

для последней строки.

Ответ 5

xor символы вместе, по четыре за раз.

Ответ 6

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;

// a variation on dan bernstein algorithm
// [http://www.cse.yorku.ca/~oz/hash.html]
template<typename Int>
struct hash {
    hash() : acc(5381) { }
    template<typename Ch>
    void operator()(Ch ch) { acc = ((acc << 5) + acc) ^ ch; }
    operator Int() const { return acc; }
    Int acc;
};

int main(int argc, char* argv[])
{
    string s("Hellp, world");
    cout << hex << showbase
        << for_each(s.begin(), s.end(), hash<unsigned long long>()) << '\n';
    return 0;
}

Ответ 7

Другой способ для небольших строк:

int hash(const char* str) {
    int hash = 0;
    int c = 0;

    while (c < std::strlen(str)) {
        hash += (int)str[c] << (int)str[c+1];
        c++;
    }
    return hash;
}

Ответ 8

Вы можете использовать функции-члены operator [] или at класса строк или итераторов для доступа к отдельному char строкового объекта без преобразования его в массив c-style char.

Чтобы хэшировать строковый объект целому числу, вам нужно будет получить доступ к каждому отдельному char строкового объекта, который вы можете сделать как:

for (i=0; i < str.length(); i++) {
    // use str[i] or str.at(i) to access ith element.
}