2012-01-10 81 views
1

有沒有辦法在C++中創建散列哈希?如何在C++中創建哈希散列?

實際上,我正在嘗試在Perl中做什麼,但只能在C++中完成。 這裏是我想有發生在C++

%hash = (
gameobject1 => { 
    position => { 
     x_loc => 43, 
     y_loc => 59, 
    } 
    rect_size => { 
     width => 5, 
     height => 3, 
    } 
    collidable => 1, 
    sounds => { 
     attack => "player_attack.ogg", 
     jump => "player_jump1.ogg", 
     jump_random => [qw/player_jump1.ogg player_jump2.ogg player_jump3.ogg/] 
    } 

}, 
gameobject2 => { 
    position => { 
     x_loc => 24, 
     y_loc => 72, 
    } 
    rect_size => { 
     width => 2, 
     height => 4, 
    } 
    sounds => { 
     attack => "goblin_attack.ogg", 
    } 
     items => [qw/sword helmet boots/] 
}, 
); 

的一點要注意的Perl代碼的例子是在gameobjects哈希值可能存在或不...即位置可能存在於gameobject1,但可能不存在對於gameobject35。

任何想法?

+0

因爲C和C++是不同的語言,所以我在你的問題中用「C++」替換了「c/C++」。如果我的假設錯了,請糾正我,而您實際上對C解決方案感興趣。 – 2012-01-10 05:55:12

+0

我很喜歡任何一種,或者哪種有意義的東西:) C++作品 – vternal3 2012-01-10 05:56:37

回答

4

Perl的哈希,讓你使用任何值。 C++是一種靜態類型語言,它不會讓你這麼做:你必須明確指定你希望哈希中的值(用C++語言,地圖)的類型。

下面是用C++ 11和升壓可能的解決方案,與一些有實力的打字:)

#include <map> 
#include <vector> 
#include <string> 
#include <boost/optional.hpp> 

// Coordinates are always like this, aren't they? 
struct coords { 
    int x_loc; 
    int y_loc; 
}; 

// Dimensions are always like this, aren't they? 
struct dims { 
    int width; 
    int height; 
}; 

// Sound maps: each string key maps to a vector of filenames 
typedef std::map<std::string, std::vector<std::string>> sound_map; 
// Item lists: looks like it's just a collection of strings 
typedef std::vector<std::string> item_list; 

// Fancy names to improve readability 
enum collidability : bool { 
    collidable = true, 
    not_collidable = false 
}; 

// A structure to describe a game object 
struct game_object { 
    // An optional position 
    boost::optional<coords> position; 
    // An optional rectangle size 
    boost::optional<dims> rect_size; 
    // Assuming "false" can mean the same as "no collidable key" 
    bool collidable; 
    // Assuming an "empty map" can mean the same as "no map" 
    sound_map sounds; 
    // Assuming an "empty vector" can mean the same as "no vector" 
    item_list items; 
    // If any of the above assumptions is wrong, 
    // sprinkle boost::optional liberally :) 
}; 

// Finally, values for our "hash" 
std::map<std::string, game_object> hash { 
    { "game_object1", 
     { 
     coords { 43, 59 }, 
     dims { 5, 3 }, 
     collidable, // remember those fancy names? 
     sound_map { 
      { "attack", { "player_attack.ogg" } }, 
      { "jump", { "player_attack.ogg" } }, 
      { "jump_random", { "player_jump1.ogg", "player_jump2.ogg", "player_jump3.ogg" } } 
     }, 
     item_list {} 
    } }, 
    { "game_object2", 
     { 
     coords { 24, 72 }, 
     dims { 2, 4 }, 
     not_collidable, 
     sound_map { 
      { "attack", { "goblin_attack.ogg" } } 
     }, 
     item_list { "sword", "helmet", "boots" } 
    } }, 
    { "game_object25", 
     { 
     boost::none, // no position 
     dims { 2, 4 }, 
     not_collidable, 
     sound_map { 
      { "attack", { "goblin_attack.ogg" } } 
     }, 
     item_list { "sword", "helmet", "boots" } 
    } } 
}; 

拋出如果你真的想要的東西如Perl的一個Perl哈希散列,你可以使用std::map<std::string, boost::any>得到在地圖上存儲任何東西的能力。但是,這需要您在從地圖獲取每個值之前測試每個值的類型。如果只有一組類型是可能的,則可以使用比boost::any更強的類型,如boost::variant

+0

你有沒有試過編譯這個?我在'hash {':error C2470:'hash'中得到錯誤:看起來像一個函數定義,但沒有參數列表;跳過明顯的身體 ,也在'dims {2,4},' 和 'sound_map {「attack」,{「player_attack.ogg」}},' – vternal3 2012-01-10 06:47:03

+0

@ vternal3:是的,這個編譯良好的GCC 4.7 。就像我在答案中提到的那樣,它使用C++ 11功能,因此您需要一個相當新的編譯器。 – 2012-01-10 07:17:52

+0

我真的很感謝你對此的幫助!你搖滾 – vternal3 2012-07-09 08:38:28

2

使用std :: map?

喜歡的東西:

#include <map> 
#include <string> 
class GameObject; 
typedef std::map<std::string, GameObject> object_map_t; 
typedef std::map<std::string, object_map_t> map_of_object_maps_t; 
+0

這是一個很好的輸入法翻譯,但它可能會有非常糟糕的表現。如果可能的話,我會考慮一些代表。 – 2012-01-10 05:26:27

+0

他的問題是如何創建哈希散列。但我同意,使用具有屬性的類將是更好的方法。 – Naddiseo 2012-01-10 05:30:34

2

這個例子可以幫助你瞭解執行:

#include <map> 
#include <string> 
#include <iostream> 
using namespace std; 

void main() { 

    map<string, map<string, int>> hash; 
    hash["A"]["A"] = 1; 
    hash["A"]["B"] = 2; 
    hash["B"]["A"] = 4; 
    hash["B"]["B"] = 8; 

    for(map<string, int>::iterator i = hash["B"].begin(); i != hash["B+"].end(); i++) { 
     cout << i->first << " - " << i->second << "\n"; 
    } 
} 

乾杯... :)