На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Использование map , Как использовать структуру как ключ?
    struct asd1{
    int a;
    int b;
    };
    struct asd2{
    int c;
    int d;
    };

    typedef pair <asd1, asd2> asd1asd2;
    map <asd1, asd2> m1;
    map <asd1, asd2> :: iterator pIter;

    Как занести в map данные?
      map[key]=value;
        Все просто. Простейший пример - тебе нужно сделать записную книжку. Там у тебя с каждой фамилией ассоциируется некоторая структура данных, содержащая телефон, адрес и т. п. информацию. Так вот - фамилия - это ключ, а структура - значение:
        CODE

        #include <map>
        #include <string>

        struct Person
        {
        std::string FirstName;
        std::string LastName;
        std::string PhoneNumber;
        std::string EMail;
        std::string Address;
        };

        std::map<std::string, Person> AddressBook;

        int main(int argc, char** argv)
        {
        // Помещаем что-то в книгу:
        Person p = {"Иван", "Иванов", "1234567", "", ""};
        Person p2 = {"Петр", "Пертов", "987654", "", ""};

        AddressBook[p.LastName] = p;
        AddressBook[p2.LastName] = p2;

        // Извлекаем:
        Person& p3 = AddressBook["Иванов"];
        Person& p4 = AddressBook["Петров"];
        }
          Спасибо, но мне это было понятно. Мне интересно как организовать сложный ключ.
          map[key]=value, если key типа
          struct asd1
          {
          int a;
          int b;
          };
          не работает
            Мне нужен ключ, содержащий 2 inta. На данный момент я просто сделал вложенный map.

            struct EventInfo
            {
            char EventName[255];
            char EventInstruction[1024];
            unsigned int SymbolID;
            unsigned char EventGroupID;
            bool NeedFixedZone;
            };
            typedef map <int, EventInfo> EventsInfoMap;

            EventsInfoMap EventsInfoTemp;
            EventsInfoMap::iterator EventsInfoTempIterator;
            typedef pair <int, EventInfo> ObjectEventsInfoPair;

            map <int, EventsInfoMap> Objects_Events;
            map <int, EventsInfoMap>::iterator Objects_EventsIterator;
            typedef pair <int, EventsInfoMap> Objects_EventsPair;
              В этом случае для сложного ключа необходимо реализовать операцию less. Например, так:
              CODE

              bool less(const asd1& a1, const asd2& a2)
              {
              return a1.a < a2.a && a1.b < a2.b;
              }
              Сообщение отредактировано: Flex_Ferrum -
                И еще как я понял из того, что вы написали pair это лажа, можно без него заносить?
                  Спасибо за less огромное.
                    QUOTE (Гость Raven @ 17.11.03, 11:26)
                    И еще как я понял из того, что вы написали pair это лажа, можно без него заносить?

                    Можно и без него. Но тот пример, который привел я, простейший. В личной практике я чаще использую такой вариант:
                    CODE

                    some_map.insert(make_pair(key, value));

                    При таком способе вставки можно узнать - было ли уже значение с таким ключем в коллекции:
                    CODE

                    bool inserted = some_map.insert(make_pair(key, value)).second;


                    Поэтому утверждать, что пара - это "лажа" нельзя.
                      CODE

                      bool less(const asd1& a1, const asd2& a2)
                      {
                      return a1.a < a2.a && a1.b < a2.b;
                      }

                      Мне такая возможность не нужна (ключи будут уникальные), но все равно интересно было узнать.
                      Спасибо.
                        Дело в другом. map упорядочивает хранимые значения по ключу (для оптимизации доступа к ним). Ключи считаются уникальными априори. По этому less нужна обязательно. Альтернативный вариант - использование hash_map. Там действительно нужна только операция равенства (equal). Но этот контейнер идет только в поставке STLPort'а.
                          class asd3
                          {
                          public:
                          bool less(const asd1& a1, const asd1& a2)
                          {
                          return a1.a < a2.a && a1.b < a2.b;
                          }
                          };
                          map <asd1, asd2, asd3 > m1;
                          asd1 f;
                          asd2 h;
                          m1[f]=h;
                          Что-то не работаетsad.gif
                            less должна быть глобальной функцией.
                              bool less(const asd1& a1, const asd1& a2)
                              {
                              return a1.a < a2.a && a1.b < a2.b;
                              }
                              map <asd1, asd2, less > m1;
                              asd1 f;
                              asd2 h;
                              m1[f]=h;
                              Тоже не работает
                              И так пробовал map <asd1, asd2, less<asd1> > m1;
                                Извини, запутал я тебя. Вмето less тебе нужно определить оператор '<':
                                CODE

                                bool operator <(const asd1& a1, const asd1& a2)
                                {
                                return a1.a < a2.a && a1.b < a2.b;
                                }

                                Ты его можешь определить и в виде внешней функции, и в виде member-function.
                                  less писать совсем не обязательно. Можно обойтись оператором < в своей структуре.
                                  CODE

                                  struct asd1
                                  {
                                  int m_a;
                                  int m_b;

                                  asd1( int a, int b) : m_a( a), m_b( b) {}
                                  bool operator < ( const asd1 &obj) const
                                  {
                                   if( m_a < obj.m_a || m_b < obj.m_b)
                                    return true;
                                   return false;
                                  }
                                  };

                                  int _tmain(int argc, _TCHAR* argv[])
                                  {
                                  map< asd1, int > m;

                                  m[ asd1( 1, 2)] = 1;
                                  m[ asd1( 1, 1)] = 0;
                                  m[ asd1( 2, 3)] = 2;
                                  m[ asd1( 0, 0)] = -1;
                                  for( map< asd1, int>::iterator iter = m.begin(); iter != m.end(); ++iter)
                                   printf( "Key: %d,%d = %d\n", iter->first.m_a, iter->first.m_b, iter->second);
                                  return 0;
                                  }

                                  //Вывод будет такой:
                                  Key: 0,0 = -1
                                  Key: 1,1 = 0
                                  Key: 1,2 = 1
                                  Key: 2,3 = 2
                                    Спасибо огромное, действительно очень нужно было. Надеюсь напишу свою первую сложную, но не корявую прогу. AlexSm отдельное спасибо за пример
                                      Objects_Events[ObjectsEventsKey(ObjectID,EventID)] = info;
                                      EventInfo a= Objects_Events[ObjectsEventsKey(ObjectID,EventID)];
                                      Проблема с извлечениемsad.gif
                                        А в чем, собственно, заключается проблема?
                                          Заношу в map нормально со сложным ключом.
                                          А извлекается ерунда
                                          EventInfo a= Objects_Events[ObjectsEventsKey(ObjectID,EventID)];
                                          EventInfo это структура value, ObjectsEventsKey(ObjectID,EventID)] - конструктор ключа
                                            А как выглядит класс EventInfo?
                                              struct ObjectsEventsKey
                                              {
                                              int ObjectID;
                                              int EventID;
                                              ObjectsEventsKey( int a, int cool.gif : ObjectID(a), EventID( cool.gif {}
                                              bool operator < ( const ObjectsEventsKey &c) const
                                              {
                                              if(ObjectID < c.ObjectID)
                                              return true;
                                              else
                                              if(ObjectID > c.ObjectID)
                                              return false;
                                              else
                                              if(EventID <= c.EventID)
                                              return true;
                                              else
                                              return false;
                                              }
                                              };

                                              struct EventInfo
                                              {
                                              char EventName[255];
                                              char EventInstruction[1024];
                                              unsigned int SymbolID;
                                              unsigned char EventGroupID;
                                              bool NeedFixedZone;
                                              int FixedZone;
                                              };
                                                map <ObjectsEventsKey, EventInfo> Objects_Events;
                                                  А посмотри, что тебе вернет операция find для твоего ключа? Если Objects_Events.end(), то проблемы с поиском ключа.
                                                    Да возвращает Objects_Events.end(), но я ведь только что его занес и size равен единице и внутри mapa данные сидят
                                                      Тогда попробуй добавить операцию сравнения ключей (оператор ==).
                                                        Причина была в некорректной функции переопределения оператора <. Я ее изменил по сравнению с написанной AlexSm
                                                          К сожалению еще остались неясные моменты. Функция find() выдает end() хотя элемент есть в mape и успешно читается через []. Когда извлекаю данные со сложный ключом (1,1), (1,2) find не выдает end(). А элементы c (2,1) (2,2) по find не находит.
                                                            Применительно к написанному мной примеру...
                                                            CODE

                                                            int _tmain(int argc, _TCHAR* argv[])
                                                            {
                                                            map< asd1, int > m;

                                                            m[ asd1( 1, 2)] = 1;
                                                            m[ asd1( 1, 1)] = 0;
                                                            m[ asd1( 2, 3)] = 2;
                                                            m[ asd1( 0, 0)] = -1;
                                                            for( map< asd1, int>::iterator iter = m.begin(); iter != m.end(); ++iter)
                                                             printf( "Key: %d,%d = %d\n", iter->first.m_a, iter->first.m_b, iter->second);

                                                            iter = m.find( asd1( 2, 3));
                                                            if( iter == m.end())
                                                             printf( "error iterator!");
                                                            else
                                                             printf( "iter->second = %d", iter->second);
                                                            return 0;
                                                            }

                                                            Прекрасно находит элементы.....
                                                              map< asd1, int > m;

                                                              m[ asd1( 1, 0)] = 1;
                                                              m[ asd1( 1, 1)] = 0;
                                                              m[ asd1( 1, 3)] = 2;
                                                              m[ asd1( 1, 4)] = -1;
                                                              m[ asd1( 2, 0)] = 1;

                                                              int a;
                                                              a=m[ asd1( 2, 0)];
                                                              if(m.find(asd1( 2, 0))==m.end())
                                                              printf("Error");

                                                              Выдает еrror, хотя элемент извлекается нормально
                                                                При таком обьявлении структуры:
                                                                CODE

                                                                struct asd1
                                                                {
                                                                int m_a;
                                                                int m_b;

                                                                asd1( int a, int b) : m_a( a), m_b( b) {}
                                                                bool operator < ( const asd1 &obj) const
                                                                {
                                                                if( m_a < obj.m_a || m_b < obj.m_b)
                                                                 return true;
                                                                return false;
                                                                }
                                                                };

                                                                У меня твой код работает, и не выдает "Error".
                                                                  QUOTE

                                                                  bool operator < ( const asd1 &obj) const
                                                                  {
                                                                  if( m_a < obj.m_a || m_b < obj.m_b)
                                                                  return true;
                                                                  return false;
                                                                  }


                                                                  Такой оператор< никуда не годиться. C помощью него например (2,1)<(1,2); (1,2)<(2,1).

                                                                  Обычно он выглядит так:

                                                                  QUOTE

                                                                  bool operator < ( const asd1 &obj) const
                                                                  {
                                                                  return  (m_a = obj.m_a ? m_b < obj.m_b : m_a < obj.m_a )
                                                                  }

                                                                    да...признаю! твой будет правильней! используемый мной работал только на положительных числах. А работал он только из-за специфики работы алгоритма сортировки map. rolleyes.gif
                                                                    Сообщение отредактировано: AlexSm -
                                                                      Да я тоже дошел до такого <. Он должен быть обнозначным при перемене параметров местами.

                                                                      Сообщения были разделены в тему "Помощь в курсовой"
                                                                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                                                      0 пользователей:


                                                                      Рейтинг@Mail.ru
                                                                      [ Script execution time: 0,0884 ]   [ 16 queries used ]   [ Generated: 7.07.25, 12:23 GMT ]