Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
#1

Структура в качестве ключа для map - C++

23.08.2013, 13:02. Просмотров 2220. Ответов 20
Метки нет (Все метки)

Доброго времени суток.

Имеется простая структура
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    struct coordinateSet
    {
    public:
 
        coordinateSet(char *X,int *Y)
        {
            this->direction_X = X;
            this->direction_Y = Y;
        }
 
        char* direction_X;
        int* direction_Y;
 
 
        bool operator<(const coordinateSet& a) const
        {
            if(*this->direction_X < *a.direction_X && *this->direction_Y < *a.direction_Y )
                return true;
            return false;
        };
 
        bool operator==(const coordinateSet& a) const
        {
            if(*this->direction_X == *a.direction_X && *this->direction_Y == *a.direction_Y )
                {return true;}
            return false;
        };
 
    };
И такая карта :
C++
1
map<coordinateSet,int> field;
Элемент добавляется, видится нормально. Но операция count выполняется не правильно - выдает "1" в любом случае если поле char* совпадает
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.08.2013, 13:02
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Структура в качестве ключа для map (C++):

MAP в качестве ключа
Есть map&lt;string, map&lt;Language, string&gt; lang; map&lt;string, map&lt;Language, string&gt;...

Map. 0 в качестве ключа [0]
Если создать словарь map и в качестве ключа использовать целые числа. Почему...

Возможно ли создать контейнер std::map, в котором в качестве значения была бы ссылка на std::map?
Здравствуйте. Возможно ли создать контейнер std::map, в котором в качестве...

Каким свойством должен обладать объект для добавления в ассоциативные контейнеры в качестве ключа?
помогите пожалуйста с правильной формулировкой и составлением ответа на такой...

В качестве ключа использовать три буквы ФИО студента. (Например, ключ поиска для Сидорова Ивана Кузьмича – СИК
Прошу помочь! Не получается поиск. (Например, ключ поиска для Сидорова Ивана...

map, условие по отсутствию ключа
У меня есть карта, и нужно организовать операцию, если в карте нет заданного...

20
BigLow
55 / 55 / 6
Регистрация: 07.07.2013
Сообщений: 345
23.08.2013, 15:28 #2
Цитата Сообщение от Kseon12 Посмотреть сообщение
if(*this->direction_X == *a.direction_X
эту вы тут хотите сравнить строки? для сравнения нужна функция strcmp(s1, s2)
0
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 15:29 #3
Цитата Сообщение от Kseon12 Посмотреть сообщение
Но операция count выполняется не правильно - выдает "1" в любом случае если поле char* совпадает
Ваш "operator==" не имеет никакого отношения к std::map::count. А оператор "operator<" не удовлетворяет условиям strict weak ordering, а именно в части "Transitivity of equivalence".
0
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
23.08.2013, 15:57  [ТС] #4
немного посидел, посмотрел ... Почему функция count вызывает оператор "<", если логично что там должно быть сравнение "==". И почему собственно он вызывается несколько раз, хотя в map всего один елемент. И не менее интересно почему даже после нескольких вызовом, все значения возращаемые были false, а сама функция вернула "1"(то есть элемент есть)

Добавлено через 6 минут
Цитата Сообщение от BigLow Посмотреть сообщение
эту вы тут хотите сравнить строки?
Дак я ведь не сроки сравниваю, а два символа
Цитата Сообщение от kamre Посмотреть сообщение
А оператор "operator<" не удовлетворяет условиям strict weak ordering
Понятно, но как решить пока не пойму...

P.S.
Count возвращает 1 или 0 в зависимости от если элемент или нету, так почему используется именно оператор "<"
0
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 16:07 #5
Цитата Сообщение от Kseon12 Посмотреть сообщение
Count возвращает 1 или 0 в зависимости от если элемент или нету
Не верно, посмотрите еще раз описание std::map::count.
0
aLarman
644 / 565 / 164
Регистрация: 13.12.2012
Сообщений: 2,112
Завершенные тесты: 1
23.08.2013, 16:12 #6
Цитата Сообщение от Kseon12 Посмотреть сообщение
так почему используется именно оператор "<"
map не требует от ключа наличие оператора ==? ему хватает оператора <
0
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
23.08.2013, 16:30  [ТС] #7
Цитата Сообщение от kamre Посмотреть сообщение
Не верно, посмотрите еще раз описание std::map::count.
прочитал, но все равно не догнал.
1 if the container contains an element whose key is equivalent to k, or zero otherwise.
Вернет 1 если элемент эквивалентный k. Если у меня структура в качестве ключа, то count должен вернуть 1 если для входной структуры есть эквивалентная. Для этого их поля должны быть одинаковые же.

Find вообще выдает ошибку на n проходе.

Не могу понять, как должен выглядеть operator<
0
Jupiter
Каратель
Эксперт С++
6568 / 3989 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.08.2013, 16:47 #8
Цитата Сообщение от Kseon12 Посмотреть сообщение
Почему функция count вызывает оператор "<"
потому что некоторые вендоры библиотек вместо == используют (!(x < y) && !(y < x))
1
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 16:54 #9
Цитата Сообщение от Kseon12 Посмотреть сообщение
для входной структуры есть эквивалентная. Для этого их поля должны быть одинаковые же.
Опять не верно, опишите какое у вас получилось отношение "эквивалентности" для вашего "operator<".
0
aLarman
644 / 565 / 164
Регистрация: 13.12.2012
Сообщений: 2,112
Завершенные тесты: 1
23.08.2013, 16:56 #10
Цитата Сообщение от Kseon12 Посмотреть сообщение
Не могу понять, как должен выглядеть operator<
а весь код можно?
0
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 16:58 #11
Цитата Сообщение от Jupiter Посмотреть сообщение
потому что некоторые вендоры библиотек вместо == используют (!(x < y) && !(y < x))
А какие вендоры используют == вместо того, что описано в стандарте:
The phrase “equivalence of keys” means the equivalence relation imposed by the comparison and not the operator== on keys. That is, two keys k1 and k2 are considered to be equivalent if for the comparison object comp, comp(k1, k2) == false && comp(k2, k1) == false.
?
1
CheshireCat
Эксперт С++
2907 / 1256 / 114
Регистрация: 27.05.2008
Сообщений: 3,451
23.08.2013, 17:05 #12
Цитата Сообщение от Jupiter Посмотреть сообщение
потому что некоторые вендоры библиотек вместо == используют (!(x < y) && !(y < x))
Я бы сказал еще определеннее, - все без исключения вендоры. Так как Ст.23.2.4/3 прямо требует не использовать оператор== для определения эквивалентности ключей, а использовать сравнивающий объект и конструкцию !comp(x, y) && !comp(y, x). В качестве же сравнивающего объекта по умолчанию используется предикат less<>. Что, впрочем, не запрещает программисту задать собственный предикат сравнения.
1
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
23.08.2013, 17:14  [ТС] #13
Цитата Сообщение от kamre Посмотреть сообщение
Опять не верно, опишите какое у вас получилось отношение "эквивалентности" для вашего "operator<".
Цитата Сообщение от Jupiter Посмотреть сообщение
(!(x < y) && !(y < x))
Выходить у меня только левая часть проверки (и то не верная)
Этот вариант тоже выдает ошибку
C++
1
if(!(this->direction_X < a.direction_X && this->direction_Y < a.direction_Y) && !(this->direction_X > a.direction_X && this->direction_Y > a.direction_Y))
Видно я не понимаю логику работы и вызова этого оператора

Цитата Сообщение от aLarman Посмотреть сообщение
а весь код можно?
Используется только тут
C++
1
map<coordinateSet,int> field;
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void PlayerBasic::print_field(void)
{
    char TOP_COORDINATES [] = {'a','b','c','d','e','f','g','h','k','l','m'};
    for(int i =0;i<10; i++)
    {
        for(int j=0;j<10;j++)
        {
            coordinateSet tmp(TOP_COORDINATES[j],i);
            std::cout << "|_";
            std::cout << field.find(tmp)->second;
                        //std::cout << field.count(tmp);
            std::cout << "_";
        }
        std::cout << "|"<<std::endl;
    }
}
0
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 17:29 #14
Цитата Сообщение от Kseon12 Посмотреть сообщение
Этот вариант тоже выдает ошибку
Предлагаю вместо своей структуры попробовать std::pair<char, int>.
1
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
23.08.2013, 17:35  [ТС] #15
Цитата Сообщение от kamre Посмотреть сообщение
Предлагаю вместо своей структуры попробовать std:air<char, int>.
Да, это определенно решит проблему. Спасибо )

Но вообще хотелось узнать как правильно такой вариант сделать
0
kamre
127 / 131 / 11
Регистрация: 25.12.2011
Сообщений: 443
23.08.2013, 17:38 #16
Цитата Сообщение от Kseon12 Посмотреть сообщение
Но вообще хотелось узнать как правильно такой вариант сделать
А что мешает посмотреть на реализацию operator< для класса std::pair?
0
gray_fox
What a waste!
1552 / 1257 / 165
Регистрация: 21.04.2012
Сообщений: 2,634
Завершенные тесты: 3
23.08.2013, 17:40 #17
Цитата Сообщение от Kseon12 Посмотреть сообщение
Но вообще хотелось узнать как правильно такой вариант сделать
http://en.cppreference.com/w/cpp/utility/pair/operator_cmp
т.е.
C++
1
2
3
4
5
6
7
if (direction_X < a.direction_X) {
   return true;
} else if (a.direction_X < direction_X) {
   return false;
} else {
   return (direction_Y < a.direction_Y);
}
1
Kseon12
61 / 3 / 1
Регистрация: 22.12.2011
Сообщений: 99
23.08.2013, 17:51  [ТС] #18
Цитата Сообщение от gray_fox Посмотреть сообщение
C++
1
2
3
4
5
6
7
if (direction_X < a.direction_X) {
* *return true;
} else if (a.direction_X < direction_X) {
* *return false;
} else {
* *return (direction_Y < a.direction_Y);
}
Да, работает, спасибо. Теперь осталось понять суть )
0
gray_fox
What a waste!
1552 / 1257 / 165
Регистрация: 21.04.2012
Сообщений: 2,634
Завершенные тесты: 3
23.08.2013, 17:58 #19
Цитата Сообщение от Kseon12 Посмотреть сообщение
Теперь осталось понять суть )
Цитата Сообщение от kamre Посмотреть сообщение
Читали?
0
aLarman
644 / 565 / 164
Регистрация: 13.12.2012
Сообщений: 2,112
Завершенные тесты: 1
23.08.2013, 18:05 #20
Цитата Сообщение от Kseon12 Посмотреть сообщение
C++
1
coordinateSet(char *X,int *Y)
Цитата Сообщение от Kseon12 Посмотреть сообщение
C++
1
coordinateSet tmp(TOP_COORDINATES[j],i);
что то я не понимаю, ту т же ни TOP_COORDINATES[j] ни i не адреса, как это работает О_О

Добавлено через 20 секунд
не указатели (поправка)
0
23.08.2013, 18:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.08.2013, 18:05
Привет! Вот еще темы с решениями:

Работа с map: нахождение ключа по значению
написал вот такой код который ищет количество повторов в ключах map //1)...

Контейнер map: реализовать проверку на уникальность ключа
Приветствую форумчан, имеется контейнер map с элементами struct Elemnts {...

Map с функциями: Как использовать функции в качестве объектов
Создал map, в котором по знаку операции( '^' к примеру) ищется бинарная...

Структура в качестве параметра шаблона
Добрый день, возник вопрос при выполнении КР по программированию: Можно ли...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru