2010-10-21 35 views
0

在上一個問題中,我在那裏做了一個大混亂。所以我想給它一個新的嘗試。結構成員名稱 - 搜索


struct emp 
{ 
    int salary; 
    string empid; 
}; 
struct payroll 
{ 
    int empid; 
    int deductions; 
}; 
    emp a1,a2, a3; 

    a1.salary = 9000; 
    a1.empid = 1; 

    a2.salary = 1000; 
    a2.empid = 2; 

    a3.salary = 9000; 
    a3.empid = 3; 

    payroll p1,p1,p3; 

    p1.empid = 1; 
    p1.deductions = 10; 

    p12.empid = 2; 
    p2.deductions = 20; 

    p3.empid = 3; 
    p3.deductions = 30; 

現在,從命令提示符我給這樣的

empid = 1; 

的話,我需要的答案是A1和P1。 在這裏,我需要檢查結構是否具有成員名稱:empid - 如果爲true - 則檢查empid = 1。
如何以通用方式執行此操作。我的意思是如果我有30個這樣的結構如何做。給我任何想法,如果這是不可能的,那麼如何使用任何其他數據結構來做到這一點。

回答

2

沒有可移植的方式來動態檢查結構的成員變量名稱。如果您不想檢查成員變量名稱,請使用std::vector來存儲結構實例。使用std::find_if來搜索滿足謂詞的特定實例。有關使用示例find_if,請參閱this link。如果你真的想檢查是否在struct存在一個名爲empid場,使用std::map代替:

typedef std::map<std::string, int> emp; 
typedef std::map<std::string, int> payroll; 
typedef std::vector<emp> emp_list; 
typedef std::vector<payroll> payroll_list; 

emp_list emps; 
emp a1; 
a1["empid"] = 1; 
a1["salary"] = 9000; 
emps.push_back(a1); 
// ... 

payroll_list pays; 
payroll p1; 
p1["empid"] = 1; 
p1["deductions"] = 10; 
pays.push_back(p1); 
// ... 

// use an iterator over emps and pays to check for specific items 
emp_list::const_iterator eit = emps.begin(); 
emp_list::const_iterator eend = emps.end(); 
while (eit != eend) 
    { 
    emp e = *eit; 
    int eid = e["empid"]; 
    if (eid == empid) 
     { 
     std::cout << e["salary"] << '\n'; 
     } 
    eit++; 
    } 
// ... 
+0

ohh ..昨天你也給我答案。是的,我爲結構實例創建了矢量。但find_if只給我第一個實例,還有一件事=>如果輸入是:salary = 9000,那麼它應該給我a1,a3(首先檢查成員名稱,接下來如果成員名稱存在 - 則值)。你能爲此寫一個示例代碼嗎? – jony 2010-10-21 10:10:38

0
  1. 你應該在所有struct的使用一致的數據類型爲empid
  2. As @Vijay Mathew suggests,使用vector然後搜索。或者,您可以使用mapempid作爲關鍵字,這將爲大量條目提供更好的性能。
+0

此empid僅用於測試目的,並且數據類型可能不相等,如果具有20列的20個結構 - 如何使用map?沒有像這樣的主鍵。如果我搜索:扣除= 30(從命令提示符:沒有其他信息),那麼該怎麼辦? – jony 2010-10-21 10:15:49

0

如果我正確理解你的問題,如果你的「數據庫」中有30個結構(表),你想要找到所有具有「empid」作爲列的結構(即結構的成員)?在C++中,我沒有意識到一種機制來測試一個結構是否有名稱的特定成員,至少不是在運行時提供的名稱。您需要以某種形式的「元數據」 - 例如具有字符串鍵地圖,列出了一組例如結構(或在邏輯與字符串比較等編碼的)...

這裏是一個草圖...

A「表」級上鍵入行類型(即結構)

class table 
{ 
    // some virtual methods common to all classes.. 
}; 

template <typename _Row> 
class data_table : public table 
{ 
    // methods 

    // real data 
    std::vector<_Row> data; 
}; 

,那麼你需要一個數據庫類來保存所有的表..

class database 
{ 
    // methods 
    std::map<int, boost::shared_ptr<table> > tables; // here int is for a unique id for table 
}; 

現在你有表,每張表是一組爲r的集合行(結構)。然後,您需要定義一些元數據數據庫,即圖列表等等。

std::multimap<std::string, boost::shared_ptr<table> > columns; 

這您在使用該結構的知識來填充,例如,該地圖可以包含,你的代碼上方:

columns["empid"] = id of table<emp>; 
columns["empid"] = id of table<payroll>; 

現在,您可以將「查詢」傳遞給您的「數據庫」類,在那裏您會說類似「empid」= 1的內容,然後在列映射中查找並查找表的所有實例,然後分別您可以使用「empid」= 1進行查詢。至於如何將「empid」映射到emp結構中的真實empid字段,則必須將該邏輯嵌入emp結構中可以委託給table<emp>的方法中(或者如果您能想到的存儲成員引用的一個聰明的辦法...)

這只是一個建議...

或者,考慮使用的M中任何可以支持真正查詢的數據庫,並以獨立或嵌入的方式運行!

編輯:

struct emp 
{ 
    int empid; 
    string empname; 

    template <typename T> 
    bool matches(const string& field_name, const T& value) 
    { 
    if (field_name == "empid") 
     return empid == value; 
    else if (field_name == "empname") 
     return empname == value; 
    // etc 
    return false; 
    } 

}; 

因此,「元數據」在測試的邏輯進行編碼,你傳遞一個字符串字段名稱,然後根據它是什麼,你比較合適的值...這不是很有效率,但它的作品...

+0

是的......它解決了慷慨的問題,但我真的在這裏觸及到「至於如何將empid」映射到結構emp中的真實empid字段「,如果我給出像這樣的輸入」emp,empid = 1「那麼如何將empid映射到emp.empid。感謝你的回答。 – jony 2010-10-21 10:45:39

+0

這是由我所謂的「元數據」處理 - 我會編輯上面的答案。 – Nim 2010-10-21 11:31:51

+0

此外,如果你需要解析「emp,empid = 1」,這是一個不同的問題,我希望你'已經解決了如何做到這一點?如果沒有,請查看任何有關引用的字符串操作(例如cplusplus.com) – Nim 2010-10-21 11:38:47