自訂hash鍵C++

來源:互聯網
上載者:User

標籤:條件   IV   集合   操作   函數參數   bsp   根據   ios   temp   

參考:https://stackoverflow.com/questions/17016175/c-unordered-map-using-a-custom-class-type-as-the-key

http://zh.cppreference.com/w/cpp/container/unordered_map/unordered_map

https://www.cnblogs.com/chixinfushui/p/9019988.html

關於寫背包問題的程式,遇到需要自訂索引值的情況。

寫的程式自訂索引值需要包含背包容量weight以及目前物品個數number兩個值,對應的索引值則是目前背包容量以及物品個數下得到的最大價值value,即目前條件下的最優解。

用c++的unordered_map儲存自訂索引值對象時.

struct Key {    std::string first;    std::string second;};

同時需要注意以下兩點:

1.聲明自己的雜湊函數,重載operator()操作符,函數參數為自訂索引值類型,返回為size_t:

struct KeyHash { std::size_t operator()(const Key& k) const {     return std::hash<std::string>()(k.first) ^            (std::hash<std::string>()(k.second) << 1); }}; //位元運算,移位元運算

2.需要一個比較函數來比較hash索引值是否相等

struct KeyEqual { bool operator()(const Key& lhs, const Key& rhs) const {    return lhs.first == rhs.first && lhs.second == rhs.second; }};

使用時:

 // 定義 KeyHash 與 KeyEqual 結構體並在模板中使用它們    std::unordered_map<Key, std::string, KeyHash, KeyEqual> m6 = {            { {"John", "Doe"}, "example"},            { {"Mary", "Sue"}, "another"}    }; 

關於STL中的unordered_map 

/*template <class Key,  :主鍵的類型 *            class T,    :被映射的值的類型 *            class Hash = hash<Key>, :一元,以一個key類型對象為參數 *            返回一個基於該對象的size_t類型的唯一值,類模板內部,使用其別名為hasher的成員類型 *            class Pred = equal_to<Key>, 二元謂詞,以兩個Key類型的對象為參數,返回一個bool值 *            如果第一個參數等價為第二個參數,該bool值為true,否則為false.預設值為std::equal_to *            class Alloc = allocator< pair<const Key, T> > *            容器內部用來管理記憶體配置及釋放的記憶體 Clerk的類型 * > class unordered_map;  *template<class Key> struct hash;  * */

寫的遞迴背包程式,感覺用遞迴還是很慢。

#include <iostream>#include <ctime>#include <string>#include <vector>#include <fstream>#include <unordered_map>#include <utility>#include <stack>#include <sstream>using namespace std;/***********物體屬性******/class item{public:    long value; //物體價值    int weight; //物體重量    item() : value(0), weight(0) {}};/***********包含物體數量以及背包容量的索引值對象,映射的value為目前容量下所能獲得的最優價值*************/class Key{public:    long weight;       //    int number;    Key(int _num, long _weight) :  number(_num), weight(_weight) {}};struct KeyHash   //自訂Hash函數{    size_t operator()(const Key& k) const    {        return std::hash<long>()(k.weight) ^                (std::hash<int>()(k.number) << 1);    }};struct KeyEqual  //自訂動作符號{    bool operator()(const Key& lhs, const Key& rhs) const    {        return lhs.number == rhs.number && lhs.weight == rhs.weight;    }};class Knapsack{public:/**************建構函式讀取資料*************/    Knapsack()    {        ifstream fin("1.txt");        string line;        stringstream stream;        if(getline(fin, line))        {            stream.clear();            stream << line;            stream >> knapsack_size;            stream >> num_of_items;        }         int cnt = 1;        init_items();        while(getline(fin, line))        {            long _value;            long _weight;            stream.clear();            stream << line;            stream >> _value;            stream >> _weight;            items[cnt].value = _value;            items[cnt].weight = _weight;            cnt++;        }    }        void init_items()    {        items.resize(num_of_items+1);    }    void dynamic() //遞迴動態規劃    {        long max_value = make(num_of_items, knapsack_size);        cout << "max_value:" << max_value << endl;    }        long make(int i_item, long weight)    {        Key find_key(i_item, weight);        unordered_map<Key, long, KeyHash, KeyEqual >::iterator got = map.find(find_key);        if( got != map.end())        {            return got->second;        }         long value1 = 0;        long value2 = 0;        if(i_item == 0)  //0件物品的情況        {            Key temp_key(0, weight);            map.insert(make_pair(temp_key, 0));            return 0;        }        value1 = make(i_item-1, weight);                if(weight >= items[i_item].weight)        {                        value2 = make(i_item-1, weight-items[i_item].weight) + items[i_item].value;            if(value2 > value1)            {                Key temp_key(i_item, weight);                map.insert(make_pair(temp_key, value2));            } else {                Key kk(i_item, weight);                map.insert(make_pair(kk, value1));                cout << value1 << endl;            }                    } else {            Key temp_key(i_item, weight);            map.insert(make_pair(temp_key, value1));        }        return value1 > value2 ? value1 : value2;    }/**************根據hash表格儲存體的值找到最優解集合****************/    void reconstruct()    {        int i = num_of_items;        int weight = knapsack_size;        while(i > 0)        {            Key k1(i, weight);            Key k2(i-1, weight);            unordered_map<Key, long, KeyHash, KeyEqual>::iterator got1 = map.find(k1);            unordered_map<Key, long, KeyHash, KeyEqual>::iterator got2 = map.find(k2);                        if(got1 != map.end() && got2 != map.end())            {                if( (got1->second > got2->second) && (weight-items[i].weight >=0) )                {                    set.push_back(i);                    weight -= items[i].weight;                    i--;                } else {                    i--;                }            }        }    }    /********列印看結果*********/    void print()    {        ofstream fout1;        fout1.open("out1.txt");        for(int i = 0; i < set.size(); i++)        {            fout1  << set[i] << " " ;        }        fcout << endl;            }public:    vector<item> items;     int num_of_items;    //物品個數    long knapsack_size;  //背包容量    unordered_map<Key, long, KeyHash, KeyEqual> map;  //自訂雜湊索引值    vector<int> set; //儲存最優解};int main(){    clock_t start, end;    start = clock();    Knapsack knapsack;    knapsack.dynamic();    knapsack.reconstruct();    knapsack.print();    end = clock();    cout << "running time:" << (double)(end-start)/CLOCKS_PER_SEC << "s" << endl;    return 0;}

 

自訂hash鍵C++

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.