Структура, содержащая карту на карте? (C ++ / STL) - PullRequest
3 голосов
/ 05 июня 2010

Мне было интересно, можно ли создать структуру, содержащую несколько переменных и карту на карте.

Что у меня есть на данный момент:

typedef std::map<std::string,double> lawVariables;  

struct ObjectCustomData {   
  std::string objectType;    
  bool global_lock;   
  std::map<std::string, lawVariables> lawData;   
 };

Затем эта структура передается другой функции как отдельный блок данных для этого объекта.

Структура структуры выглядит следующим образом: Каждый объект имеет блок данных, который содержит: его ObjectType, логическое значение для блокировки и различное количество «законов», которые могут выглядеть следующим образом:

law1 -> var_a = 39.3;
     -> var_g = 8.1;
law8 -> var_r = 83.1;
     -> var_y = 913.3;
     -> var_a = 9.81;

Во-первых, я не уверен, стоит ли мне использовать Карту внутри Карты, и, во-вторых, даже если это будет допустимо, я не уверен, как заполнить ее данными и как впоследствии вызвать ее. Я посмотрел на карты, потому что тогда я могу искать (по имени), если определенный объект имеет определенный закон, и если этот закон имеет определенные переменные.

(извините за появление первого беспорядочного сообщения, надеюсь, что так будет лучше :))

Ответы [ 3 ]

2 голосов
/ 05 июня 2010

Мне было интересно, можно ли создать структуру, содержащую ряд переменные и карта на карте

Да. Карту можно использовать в качестве значения внутри другой карты.

Если вы точно знаете порядок вставки, а количество записей меньше для внутренней карты, то ваша структура данных может выглядеть следующим образом:

typedef std::vector<std::pair<std::string,double> > lawVariables;  

struct ObjectCustomData {   
  std::string objectType;    
  bool global_lock;   
  std::map<std::string, lawVariables> lawData;   
 };

EDIT : Я видел ваше редактирование сейчас. Если поиск является вашим основным требованием, тогда перейдите на карту.

Пример:

 typedef std::map<std::string,double> lawVariables;  

    struct ObjectCustomData {   
      std::string objectType;    
      bool global_lock;   
      std::map<std::string, lawVariables> lawData;   
     };

void test(ObjectCustomData& data)
{
  lawVariables& variable = data.lawData["law_1"];
  variable["var_a"] = 39.3;

}
1 голос
/ 05 июня 2010

Что у вас должно работать. Вы можете загрузить данные так:

  ObjectCustomData data;
  data.lawData["law_1"]["var_a"] = 39.3;
  data.lawData["law_1"]["var_g"] = 8.1;
  data.lawData["law_8"]["var_r"] = 83.1;
  .
  .
  .

Вы можете проверить наличие таких элементов:

  if (!data.lawData.count("law_x")) {
    cout<<"law_x not found"<<endl;
  }

  if (data.lawData.count("law_1")) {
    cout<<"law_1 was found"<<endl;
  }
0 голосов
/ 05 июня 2010

Просто добавьте следующее, если кто-то другой может его искать: (обратите внимание, что некоторые из них могут остаться неиспользованными или около того, дайте мне знать! :))

в .ч:

typedef std::map<std::string,double> lawVariables;
typedef std::map<std::string,double>::iterator lawVars;
struct ObjectCustomData {
    std::string objectType;
    bool global_lock;
    std::map<std::string, lawVariables> lawData;
};


template <typename K, typename V, class C, class A>
std::ostream &operator<< (std::ostream &os, std::map<K,V,C,A> const& m)
{
    os << "{ ";
    typename std::map<K,V,C,A>::const_iterator p;
    for (p = m.begin(); p != m.end(); ++p) {
        os << p->first << ":" << p->second << ", ";
    }
    return os << "}";
}

Примечание: шаблонные материалы таковы, что вы можете просто отслеживать всю карту в карте.

    void setCustomData();
    void showCustomData();
    bool checkLaw(std::string law);
    bool checkVar(std::string law,std::string var);
    double getLawVar(std::string law, std::string var);
    template<class T,class A>
    void showMap(const std::map<T, A>& v);
    ObjectCustomData ocd;

примечание: setCustomData просто заполняет карту карты некоторыми случайными данными для целей тестирования, showCustomData просто использует шаблон и пользовательский оператор для отображения всей карты. checkLaw и checkVar удостоверяются, что определенное значение даже существует, и getLawVar возвращает значение определенного значения определенного закона. showMap показывает весь контент map-in-map с несколько более приятным выводом.

в .cpp:

Я пропущу setCustomData, это просто набор ocd.lawData [law] [var] = 123.45;

    void showCustomData() {
        std::cout <<ocd.lawData<<std::endl; 
    }
    bool checkLaw(std::string law){
        if ((int)ocd.lawData[law].size() != 0) {
            return true;
        }
        else {
            return false;
        }   
    }
    bool checkVar(std::string law, std::string var){        
        lawVars lVars = ocd.lawData[law].find(var);
        if(lVars != ocd.lawData[law].end()){
            return true;
        }
        else {
            return false;
        }
    }
    double getLawVar(std::string law, std::string var){
        if (checkLaw(law) && checkVar(law, var)){
            return ocd.lawData[law].find(var)->second;
        }
        else {return 0.0;}
    }
    template<class T, class A>
    void showMap(const std::map<T, A>& v) {
        for (std::map<T, A>::const_iterator ci = v.begin(); ci != v.end(); ++ci) {
            std::cout << ci->first <<" -> ";
            lawVariables tmpLaw = ci->second;
            lawVars lVars;
            for (lVars = tmpLaw.begin(); lVars != tmpLaw.end(); lVars++){
                std::cout << lVars->first << " : " << lVars->second <<"\t";
            }
            std::cout<<std::endl;
        }
        std::cout<<std::endl;
    }

Надеюсь, это хотя бы несколько полезно для кого-то, не стесняйтесь комментировать вещи, которые я мог бы / должен сделать лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...