【问题标题】:structure member name - search结构成员名称 - 搜索
【发布时间】:2010-10-21 19:36:49
【问题描述】:

在上一个问题中,我把那里弄得一团糟。所以我想给它一个新的尝试。


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 个这样的结构该怎么办。给我任何想法,如果这是不可能的,那么如何使用任何其他数据结构来做到这一点。

【问题讨论】:

    标签: c++ structure


    【解决方案1】:

    没有可移植的方法来动态检查结构的成员变量名称。如果您不想检查成员变量名称,请使用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++;
      }
    // ...
    

    【讨论】:

    • 哦.. 昨天你也给了我答案。是的,我为结构实例创建了向量。但是 find_if 只给了我第一个实例,还有一件事 => 如果输入是:salary=9000,那么它应该给我 a1、a3(首先检查成员名称,然后是成员名称,然后是值)。你能为此写一个示例代码吗?
    【解决方案2】:
    1. 您应该在所有structs 中为empid 使用一致的数据类型。
    2. 作为@Vijay Mathew suggests,使用vector 然后搜索。或者,您可以使用 mapempid 作为键,这将为大量条目提供更好的性能。

    【讨论】:

    • 这个empid只是为了测试目的,如果有20个20列的结构,数据类型可能不相等-如何使用map???没有这样的主键。如果我搜索:deductions = 30(从命令提示符:没有其他信息),那该怎么办?
    【解决方案3】:

    如果我正确理解您的问题,如果您的“数据库”中有 30 个结构(表),您想查找所有以“empid”为列的结构(即结构的成员)?在 C++ 中,我不知道有一种机制来测试结构是否按名称具有特定成员,至少不是在运行时提供的名称。您需要以某种形式的“元数据”存储它 - 例如带有字符串键的映射,例如列出一组结构(或用字符串比较等逻辑编码)...

    这是一个粗略的草图......

    按行类型(即结构)键入的“表”类

    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
    };
    

    现在您有了一组表,其中每个表都是一组行(结构)。然后,您需要为数据库定义一些元数据,即将列映射到表等。

    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&lt;emp&gt;可以委托给(或者如果你能想到一种存储对成员的引用的聪明方法......)

    这只是一个建议……

    或者,考虑使用支持真实查询并作为独立或嵌入式运行的众多数据库之一!

    编辑:

    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;
      }
    
    };
    

    所以“元数据”在逻辑中被编码为测试,你传入一个字符串字段名,然后根据它是什么,你比较适当的值......这不是很有效,但它有效...

    【讨论】:

    • 是的......它解决了慷慨的问题,但我真的在这里“至于如何将“empid”映射到结构emp中的真正empid字段”,如果我这样输入"emp, empid = 1" 那么如何将 empid 映射到 emp.empid。谢谢你的回答。
    • 另外,如果您需要解析“emp, empid=1”,这是一个不同的问题,我希望您已经知道如何做到这一点??如果没有,请查看任何引用的字符串操作(例如 cplusplus.com)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多