> Как проще выполнить реверсию значений элементов для заданного контейнера > std::map? То есть ключи остаются на месте, а меняются в обратном порядке
Порядок хранения элементов в std::map не определён. Обратным порядком для
неоределённого порядка будет также неопределённый порядок. Следовательно,
тебе ПРОСТО НЕ НУЖНО НИЧЕГО ДЕЛАТЬ.
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>На самом деле ваш аргумент вообще не состоятелен. Так как с таким же успехом можно сказать, что алгоритм reverse вообще не нужен ни для вектором, ни для списков, так как можно работать с обратными итераторами. Но тем не менее такой алгоритм существуетт, а значит существуют задачи, где он необходим.
J>Какой аргумент? Что для обратного обхода есть итераторы и надо пользоваться ими, благо скорость одна и та же будет? Ну так это же медицинский факт
J>Ну и я задачу так и не услышал. Реальную задачу, а не то, как ты ее пытаешься решить при помощи std::map, требуя реверса. J>Вряд ли ведь задача ставится в терминах мапа и ключей-значений, правда?
Так ч и не собираюсь придумывать реальную задачу. Реальные задачи существуют помимо вашей и меой фантазии. Вы не на то облращаете внимание! Не беспокойтесь, как я уже сказал, мир реальных задач значительно богаче вашей фантазии, что вам даже и не снилось, какие задачи могут встретиться на практике. Я вам уже сказал, что ваш аргумент не состоятелен, так как согласно ему, вообще непонятно, зачем существует этот алгоритм, например, для векторов?
Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
Здравствуйте, Сыроежка, Вы писали:
С>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
Потому что алгоритм reverse для контейнеров std::vector и std::list не изменяет сами хранимые сущности, а только меняет их порядок.
В случае std::map хранимой сущностью является пара "ключ-значение", которые контейнер std::map хранит в порядке, задаваемом ключами и предикатом.
Твой reverse для std::map не переставляет сущности, а изменяет их.
Т.е., из одного набора данных нужно получить полностью другой набор данных, а алгоритм — трансформирующий.
Ну а поскольку трансформаций может быть сколько угодно, а не только "обменять значения", в общем виде такого алгоритма у самого контейнера нет.
Имею скафандр — готов путешествовать!
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, rus blood, Вы писали:
RB>Здравствуйте, Сыроежка, Вы писали:
С>>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
RB>Потому что алгоритм reverse для контейнеров std::vector и std::list не изменяет сами хранимые сущности, а только меняет их порядок. RB>В случае std::map хранимой сущностью является пара "ключ-значение", которые контейнер std::map хранит в порядке, задаваемом ключами и предикатом. RB>Твой reverse для std::map не переставляет сущности, а изменяет их. RB>Т.е., из одного набора данных нужно получить полностью другой набор данных, а алгоритм — трансформирующий. RB>Ну а поскольку трансформаций может быть сколько угодно, а не только "обменять значения", в общем виде такого алгоритма у самого контейнера нет.
Я не соогласен с вашей позицией, так как в std::map а значение как раз является неконстантным и может меняться. То есть ключ больше относится не к значению, а к организации хранения данных в конкретном типе уонтейнера. То есть в векторе вы можете обращаться к элементамс вектора по индексу элемента, как, например, v[0], v[1] и т.д., а в std::map индекс заменяется ключом, как, например, m[key1], m[key2] и т.д.
То есть ключ — больше выполняет роль указателя или индекса доступа к данным. Сами же данные можно менять, то есть они могут размещаться по другому индексу или ключу точно также, как и векторе.
Конечно у каждого контейнера есть специфика хранения данных, но тем не менее семаника reverse достатончо прозрачна. Она обычно относится к самим данным независимо от способа их организации и хранения. То есть когда мы говорим о std::map мы естественно должны понимать специфику организации этого котейнера, а, сооответственно, алгоритм reverse должен отражать в себе эту специфику для этого контейнера. Исходя из этой позиции, я не вижу каких-то среьезных причин не даптировать этот алгоритм для данного коонтейнера. Такачя адаптация моогла бы быть выполнена с помощью функции-члена класса этого контейнера.
Пример такой адаптации я вижу в функции-члене класса insert, где указывается позиция, перед которой надо вставить новый элемент. Но вы хорошо понимаете, что тем не менее элемент не будет вставлен именно перед этой позицией в std::map. Но джля сохранения унифицированного подхода список параметров этой функции остается прежним, как и для других контейнеров, хотя ее действие не соответствует действию аналогичных функций других контейнеров. То есть учитывается специфика std::map, но формально сохраняется общий подход. То же самое можно было бы сделать и с reverse.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Так ч и не собираюсь придумывать реальную задачу. Реальные задачи существуют помимо вашей и меой фантазии. Вы не на то облращаете внимание! Не беспокойтесь, как я уже сказал, мир реальных задач значительно богаче вашей фантазии, что вам даже и не снилось, какие задачи могут встретиться на практике. J>"Не пытайтесь это понять, понять это невозможно" (c) J>Т.е. ты придумываешь сам себе развлечения, не имеющие отношения к реальности? Тоже дело
С>>Я вам уже сказал, что ваш аргумент не состоятелен, так как согласно ему, вообще непонятно, зачем существует этот алгоритм, например, для векторов? С>>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д. J>Я тебе открою тайну — вектор, как и список, не поддерживает свою отсортированность. Т.е. ты отсортировал его, а после это можешь джелать все, что хочешь, в т.ч. сортированность нарушить. Поэтому и есть sort, reverse, random_shuffle и другие веселые алгоритмы, которые в принципе отсутствуют для контейнеров, поддерживающих свою отсортированность. J>А мап и сет — это контейнеры, сохраняющие свою отсортированность при любых операциях, и эта отсортированность поддерживается компаратором, который ты изменить для данного объекта не можешь (что имеет смысл, в общем-то), учитывая, что ты можешь хранить итераторы внутрь контейнера, с соответствующими гарантиями. И любые манипуляции с порядком элементов за пределами компаратора нарушат главное свойство — отсортированность.
J>Так что твой reverse может иметь смысл исключительно в терминах смены компаратора, что запрещено — а это значит, что ты должен создать новый объект мапа/сета с новым компаратором, который будет работать наоборот, и перекинуть данные в него — тогда все будет как надо.
J>Еще вариант — использовать boost::multi_index: там можно извращаться как угодно.
J>Я ответил на твой вопрос?
Не просветите меня, с каких это пор список не поддерживает свою организацию хранения данных?! Как раз каждый контейнерсуществует самостоятельно именно из-за того, что поддерживает собственную организацию хранения данных.
Что касается всего остального, то это говорит, что вы не в состоянии мыслить концептуально. Вы относитеьс к тем людям, которые не в состоянии обощать, а постоянно решаете частные вопросы. Для программиста — это серьезный недостаток. Я вам советую исправлять его!
Здравствуйте, Сыроежка, Вы писали:
С>Меня удивило, что в контейнере std::map нет функции-члена reverse
Тут ничего удивительного нет. std::map — это ассоциативный массив (ключ-значение), работа с которым предполагается как с фиксированными парами с доступом по ключу.
Более того, в некоторых языках программирования ассоциативные массивы реализуются как хеш-таблицы, где вообще понятие "порядок ключей" не имеет смысла.
Подробности можно почитать здесь.
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Здесь вопрос не о включении абсолютно всего, так как стандартный алгоритм уже включен в библиотеку. То есть нужно лишь сделать так, чтобы std::map не остался не охваченным.
M>Ну, можно было бы ввести трансформирующие итераторы для работы с mapped values.
Ну так все это в бусте сто лет есть, просто Сыроежке шашечки нужны, а не ехать. У него даже задачи нет, в которой это могло бы понадобиться, кроме задачи обозвать никому сто лет не нужную функцию "существенным упущением стандарта".
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, rumit7, Вы писали:
R>>Здравствуйте, Сыроежка, Вы писали:
С>>>Здравствуйте, rumit7, Вы писали:
R>>>>Здравствуйте, Сыроежка, Вы писали:
С>>>>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>>>>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>>>>
R>>>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>>>>Так что — нарушает стандарт или нет?
С>>>Здесь не все так просто, как кажэется,
R>>Я задал простой вопрос. На простой вопрос можно ответить просто — да или нет.
С>>>так как вы можете специализировать функцию swap для элементов вашего контейнера. Так что это на усмотрение пользователя контейнера, предоставляет он такую функцию или нет.
R>>Это все отмазки.. Поменьше кидайтесь громкими фразами, реже придется выглядить глупо..
С>Это не отговорки. Вы в своем пространстве имен заводите функцию swap для вашей специализации класса std:::paiir, и получаете swapable элементы контейнера. С>То есть фоормально сттандарт говорит о том, есть ли у него под рукой функция swap, которую он может применить или нет. Это уже на ваше усмотрение, предоставлять компилятору такую функцию или нет.
Ну в общем Вы признаете себя пустословом! Удачного Вам выпендрежа на Вашем любимом форуме..
Re[2]: Разместить в обратном порядке отображаемые значения s
Спасибо за пример. Но я наверное нечетко сформулировал свой исходный вопрос. Меня удивило, что в контейнере std::map нет функции-члена reverse Естественно я сделал предположение, что если такой функции-члена класса нет, то наверное легко эту операцию сделать с помощью стандартных алгоритмов. но стандартный алгоритм std::reverse по понятным причинам не подходит.
Поэтому и возник вопрос, как с помощью стандартных алгоритмов сделать подобную операцию для std::map. Может быть в boost такой алгоритм существует, если с помощью стандартных алгоритмов нужно исхитряться?
Здравствуйте, Сыроежка, Вы писали:
С>Так ч и не собираюсь придумывать реальную задачу. Реальные задачи существуют помимо вашей и меой фантазии. Вы не на то облращаете внимание! Не беспокойтесь, как я уже сказал, мир реальных задач значительно богаче вашей фантазии, что вам даже и не снилось, какие задачи могут встретиться на практике.
"Не пытайтесь это понять, понять это невозможно" (c)
Т.е. ты придумываешь сам себе развлечения, не имеющие отношения к реальности? Тоже дело
С>Я вам уже сказал, что ваш аргумент не состоятелен, так как согласно ему, вообще непонятно, зачем существует этот алгоритм, например, для векторов? С>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
Я тебе открою тайну — вектор, как и список, не поддерживает свою отсортированность. Т.е. ты отсортировал его, а после это можешь джелать все, что хочешь, в т.ч. сортированность нарушить. Поэтому и есть sort, reverse, random_shuffle и другие веселые алгоритмы, которые в принципе отсутствуют для контейнеров, поддерживающих свою отсортированность.
А мап и сет — это контейнеры, сохраняющие свою отсортированность при любых операциях, и эта отсортированность поддерживается компаратором, который ты изменить для данного объекта не можешь (что имеет смысл, в общем-то), учитывая, что ты можешь хранить итераторы внутрь контейнера, с соответствующими гарантиями. И любые манипуляции с порядком элементов за пределами компаратора нарушат главное свойство — отсортированность.
Так что твой reverse может иметь смысл исключительно в терминах смены компаратора, что запрещено — а это значит, что ты должен создать новый объект мапа/сета с новым компаратором, который будет работать наоборот, и перекинуть данные в него — тогда все будет как надо.
Еще вариант — использовать boost::multi_index: там можно извращаться как угодно.
Здравствуйте, Сыроежка, Вы писали:
С>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
Зачем?
Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
Здравствуйте, andy1618, Вы писали:
A>Здравствуйте, Сыроежка, Вы писали:
С>>Меня удивило, что в контейнере std::map нет функции-члена reverse
A>Тут ничего удивительного нет. std::map — это ассоциативный массив (ключ-значение), работа с которым предполагается как с фиксированными парами с доступом по ключу. A>Более того, в некоторых языках программирования ассоциативные массивы реализуются как хеш-таблицы, где вообще понятие "порядок ключей" не имеет смысла. A>Подробности можно почитать здесь.
Непонятно, почему заминусовали данный ответ. Ну, конечно, можно придраться, что порядок элементов в map зависит от ключа и это иногда нужно.
Однако операции для map, которые переставляют значения для ключей типа reverse, уж совершенно лишены смысла. Ведь это совсем не то, что перебрать элементы
через rbegin, rend а совсем другое. Ясно, что такую задачу, когда это полезно придумать можно, но это не отвечает тому, для чего задумывался map.
С таким же основанием можно было бы потребовать добавить функции-член для подсчета среднего гармонического значения от элементов контейнера и т.д. и т.п
Re[3]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
С>>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
J>>Зачем? J>>Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
С>Я вас уверяю, что задачи, возникающие на практике. значительно разнообразнее, чем может представить ваша фантазия в данный момент!
Этот комментарий, безусловно, всё прояснил, и главное, ответил на вопрос "зачем".
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
С>Вы просто не понимаете, что вектор можно рассматривать как отсортированный контейнер, ключом которого является индекс элемента! Создайте std::map с ключом, равным числам натурального ряда последовательно, например, от 0 до 99, и фактически, ваш контейнер будет представлять собой вектор! Только и всего! То есть можно концептуально рассматривать вектор, как некоторый частный случай std::map (раз вы не ведете речь о физической организации, а говорите лишь об отсортированности по ключу), в котором ключем является индекс элемента! С>например, рассмотрите код, чтобы было вам понятно
С>
С>Фактически здест имеют место быть пары { ключ, значение }, где ключом является индекс элемента. Причем последовательность априори отсортирована по индексу элемента!
Дорогой наш мыслитель концептуально! Ваша концептуальнейшая и обобщеннейшая теория имела бы смысл в том случае, если бы ключ и значение внутри std::map являлись бы взаимно независимыми сущностями, как например это происходит для вектора (это так, даже если смотреть на это обобщенно и концептуально, т.к. индекс никак не зависит от значения которое туда захотят засунуть!).
то я могу еще понять смысл операции reverse, т.к. индексы остаются независимой сущностью и не зависят от значения которое там хранится (программист все также будет первый, директор второй, а уборщица третьей).
reverse(staff.begin(), staff.end());
Но std::map в том виде, в котором задумывался и был воплощен имеет все же другой смысл (цитата из wikipedia): "Ассоциативный массив (словарь) — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу". Обратите ваше внимание на тот факт, что слова ключ и значение используется вместе как единое целое, и обозначаются словом "пара". Т.е. предлагаемый Вами reverse должен переворачивать часть единого целого.
С>например, рассмотрите код, чтобы было вам понятно
// внимание код не компилируемый!!!struct student{
string sname;
string name;
};
student all_students[] = {{"Петров","Петя"},{"Иванов","Ваня"},{"Егорушкин","Жора"},{"Ссылкин","Ссылка"}};
reverse(begin(all_students), end(all_students));
// после этого, по Вашей логике, нормальным результатом будет
// Петров Ссылка
// Иванов Жора
// Егорушкин Ваня
// Ссылкин Петя
Re[12]: Разместить в обратном порядке отображаемые значения
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
С>>Вы просто не понимаете, что вектор можно рассматривать как отсортированный контейнер, ключом которого является индекс элемента! Создайте std::map с ключом, равным числам натурального ряда последовательно, например, от 0 до 99, и фактически, ваш контейнер будет представлять собой вектор! Только и всего! То есть можно концептуально рассматривать вектор, как некоторый частный случай std::map (раз вы не ведете речь о физической организации, а говорите лишь об отсортированности по ключу), в котором ключем является индекс элемента! С>>например, рассмотрите код, чтобы было вам понятно
С>>
С>>Фактически здест имеют место быть пары { ключ, значение }, где ключом является индекс элемента. Причем последовательность априори отсортирована по индексу элемента!
R>Дорогой наш мыслитель концептуально! Ваша концептуальнейшая и обобщеннейшая теория имела бы смысл в том случае, если бы ключ и значение внутри std::map являлись бы взаимно независимыми сущностями, как например это происходит для вектора (это так, даже если смотреть на это обобщенно и концептуально, т.к. индекс никак не зависит от значения которое туда захотят засунуть!).
R>Например, если бы std::map создавался как-то так:
R>
R>то я могу еще понять смысл операции reverse, т.к. индексы остаются независимой сущностью и не зависят от значения которое там хранится (программист все также будет первый, директор второй, а уборщица третьей).
R>
R>reverse(staff.begin(), staff.end());
R>
R>Но std::map в том виде, в котором задумывался и был воплощен имеет все же другой смысл (цитата из wikipedia): "Ассоциативный массив (словарь) — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу". Обратите ваше внимание на тот факт, что слова ключ и значение используется вместе как единое целое, и обозначаются словом "пара". Т.е. предлагаемый Вами reverse должен переворачивать часть единого целого.
С>>например, рассмотрите код, чтобы было вам понятно
R>
R>// внимание код не компилируемый!!!
R>struct student{
R> string sname;
R> string name;
R>};
R>student all_students[] = {{"Петров","Петя"},{"Иванов","Ваня"},{"Егорушкин","Жора"},{"Ссылкин","Ссылка"}};
R>reverse(begin(all_students), end(all_students));
R>// после этого, по Вашей логике, нормальным результатом будет
R>// Петров Ссылка
R>// Иванов Жора
R>// Егорушкин Ваня
R>// Ссылкин Петя
R>
А ключ и значение как раз и являются независимыми. То есть что это означает? что для ззаданнного ключа может быть в любое время указано совершенно другое значение!
Но в любом случае спасибо вам за участие. Я уже всю дискуссию подытожил в своем сообщении по адресу http://clipper.borda.ru/?1-6-0-00000022-000-0-0-1326309482
Почитайте, будет вам интересно. Я не думаю, что что-то принципиально новое вы сможете мне возразить. То есть я не вижу никаких серьезных контраргументов моей постановке вопроса.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
С>>Вы просто не понимаете, что вектор можно рассматривать как отсортированный контейнер, ключом которого является индекс элемента! Создайте std::map с ключом, равным числам натурального ряда последовательно, например, от 0 до 99, и фактически, ваш контейнер будет представлять собой вектор! Только и всего! То есть можно концептуально рассматривать вектор, как некоторый частный случай std::map (раз вы не ведете речь о физической организации, а говорите лишь об отсортированности по ключу), в котором ключем является индекс элемента! С>>например, рассмотрите код, чтобы было вам понятно
С>>
С>>Фактически здест имеют место быть пары { ключ, значение }, где ключом является индекс элемента. Причем последовательность априори отсортирована по индексу элемента!
R>Дорогой наш мыслитель концептуально! Ваша концептуальнейшая и обобщеннейшая теория имела бы смысл в том случае, если бы ключ и значение внутри std::map являлись бы взаимно независимыми сущностями, как например это происходит для вектора (это так, даже если смотреть на это обобщенно и концептуально, т.к. индекс никак не зависит от значения которое туда захотят засунуть!).
R>Например, если бы std::map создавался как-то так:
R>
R>то я могу еще понять смысл операции reverse, т.к. индексы остаются независимой сущностью и не зависят от значения которое там хранится (программист все также будет первый, директор второй, а уборщица третьей).
R>
R>reverse(staff.begin(), staff.end());
R>
R>Но std::map в том виде, в котором задумывался и был воплощен имеет все же другой смысл (цитата из wikipedia): "Ассоциативный массив (словарь) — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу". Обратите ваше внимание на тот факт, что слова ключ и значение используется вместе как единое целое, и обозначаются словом "пара". Т.е. предлагаемый Вами reverse должен переворачивать часть единого целого.
С>>например, рассмотрите код, чтобы было вам понятно
R>
R>// внимание код не компилируемый!!!
R>struct student{
R> string sname;
R> string name;
R>};
R>student all_students[] = {{"Петров","Петя"},{"Иванов","Ваня"},{"Егорушкин","Жора"},{"Ссылкин","Ссылка"}};
R>reverse(begin(all_students), end(all_students));
R>// после этого, по Вашей логике, нормальным результатом будет
R>// Петров Ссылка
R>// Иванов Жора
R>// Егорушкин Ваня
R>// Ссылкин Петя
R>
Что касается открытия темы, то я просто тхотел выяснить, действительно не существует общерпиятой простой замены std::reverse для контейнера std::map, или я просто не тзнаю такой замены. Так как одна голова хорошо, а две лучше. Я же не обязан знать все трюки программирования, которые используются.
Как оказалось в ходе дискусии, я оказался прав, то есть нет общепринятого метода размещения значений в std::map в обратном порядке.
Это серьезое упущение стандарта С++.
Здравствуйте, Сыроежка, Вы писали:
С>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего,
Выполняется.
С>а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap.
Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
То, чего вы хотите — это итератор по значениям std::map. К паре таких итераторов будет применим стандартный алгоритм std::reverse. И они уже реализованы в библиотеке boost::range.
И тем не менее, это не отменяет того, что перестановка значений при сохранении ключей осмысленна только в узком частном случае, когда ключи образуют непрерывный отрезок натурального ряда.
Re[21]: Разместить в обратном порядке отображаемые значения
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
C>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма.
Проблему свопа пар с константой решить нельзя в принципе.
Новая форма алгоритма для мапа также не нужна, на этот счет есть бритва Оккама.
map предоставляет двунаправленный итератор по парам ключ+значение.
Используя Boost.Iterator, можно легко превратить этот итератор в двунаправленный же итератор по значениям, после чего можно применять к нему любые стандартные алгоритмы, включая reverse, random_shuffle, permutation и т.д.
Это — единственный осмысленный путь, а то, что предлагаешь ты — концептуально неправильно.
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, rumit7, Вы писали:
R>>Здравствуйте, Сыроежка, Вы писали:
С>>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>>
R>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>>Так что — нарушает стандарт или нет?
С>Здесь не все так просто, как кажэется,
Я задал простой вопрос. На простой вопрос можно ответить просто — да или нет.
С>так как вы можете специализировать функцию swap для элементов вашего контейнера. Так что это на усмотрение пользователя контейнера, предоставляет он такую функцию или нет.
Это все отмазки.. Поменьше кидайтесь громкими фразами, реже придется выглядить глупо..
Re: Разместить в обратном порядке отображаемые значения std:
Здравствуйте, Сыроежка, Вы писали:
С>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
Предлагаю банить в /forum/cpp/* по слову клиппер в сообщении за необратимое поражение мозга оным клиппером.
Re[9]: Разместить в обратном порядке отображаемые значения s
С>Вы этот пункт покажите для автора предудыщего сообщения. Надо конструктивно обсуждать вопрос, а не заниматься поясничаньем. Иначе любую тему можно превратить в профонацию! Так что будьте объективны. Иначе как окликнется, так и аукнется!
Ты прости, пожалуйста, но твой стиль вести "конструктивное обсуждение" в лучшем случае тянет на демагогию, в худшем на графоманство.
Re: Разместить в обратном порядке отображаемые значения std:
Здравствуйте, Сыроежка, Вы писали:
С>Задача простая: для заданного контейнера std::mapреверсировать отображаемые значения.
Таки расскажите, что значит реверсировать7
С>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map. Если он не включен, то наверное предполагается, что сделать это просто с помощью стандартных алгоритмов. Ведь какие основные принципы включения или не включения алгоритмов к ачестве функций-членов контейнеров? Первое- это невозможность сделать данную операцию с помощью стандартного алгоритма. например, стандартный алгоритм std::sort требует наличия итераторов произвольного доступа. Так как в контейнере std::list итератор не является итератором произвольного доступа, то этот алгоритм включили в качестве функции-лена класса для контейнера std::list Второе — это если делать алгоритм членом класса, то можно достичь большей эффективности. Такие алгоритмы включены, например, в класс std::basic_string. С>Поэтому и возник вопрос, раз алгоритм reverse не включен в контейнер std::map в качестве члена класса, то наверное его можно как-то достаточно просто реализовать с помощью стандартных алгоритмов? да причем так, чтобы каждый программист не открывал для себя заново велосипед.
map уже сортирован по ключу. итераторов произвольного доступа нет, и, имхо, не будет, если и будут, то с временем доступа O(N).
Здравствуйте, Сыроежка, Вы писали:
I>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>Так сложности нет и в том, чтобы написать все стандартные алгоритмы!
Раз нет сложности, то напиши и используй.
С>Только зачем каждый раз это делать, вы можете объяснить?
Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит.
Даже если вас съели, у вас как минимум два выхода.
Re[6]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, baily, Вы писали:
B>>Непонятно, почему заминусовали данный ответ. Ну, конечно, можно придраться, что порядок элементов в map зависит от ключа и это иногда нужно. U>std::map — это не просто какой-то там ассоциативный контейнер, это контейнер, предоставляющий некие гарантии по сложности операций, по интерфейсу и по семантике U>крайне интересным считаю документацию контейнеров от SGI : http://www.sgi.com/tech/stl/Map.html U>там формально введена некая классификация контейнеров и вы можете убедиться, что std::map удовлетворяет моделям Unique Sorted Associative Container, Pair Associative Container U>именно подобные модели позволяют для конкретно этого контейнера реализовывать алгоритмы, которые не прикрутишь к другим ассоциативным контейнерам типа хеш-таблиц U>в частности, алгоритм ТС применим к std::map и не применим к хеш-таблицам, потому что там нет порядка ключей
Это как раз и относится к тем придиркам, которые я имел ввиду, когда говорил, что в map порядок элементов зависит от ключа.
Что такое map и чем он отличается от hash_map я прекрасно знаю.
B>>Однако операции для map, которые переставляют значения для ключей типа reverse, уж совершенно лишены смысла. U>операция не лишена смысла, в ней заинтересован ТС и уже дали даже один вариант реализации
Ну так и подсчитать среднее гармоническое для элементов map, тоже не лишена смысла и наверняка кому то нужна.
И реализовать ее тоже не сложно. Могу привести даже несколько вариантов реализации, если это вам кажется таким важным.
Проблема только в том, что если начать добавлять такие "нужные" операции в интерфейс класса, то с ним работать будет невозможно.
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Кстати сказать, сейчас пришла забавная аналогия с конкурсом красоты среди женщин. Каждая претендентка имеет свой заранее определенный порядковый номер. Они так и выходят на сцену с прикрепленными сбоку номерами. Но после каждого выступления претенденток жюри переставляет барышень в соответствии с набранными очками за красоту или за еще какой-то показатель. То есть говорят: "Вы поменяйтесь местами, и вы поменяйтесь местами". И на следующем этапе конкурса барышни выходят на сцену именно в том порядке, как их жюри поменяла, хотя исходные номера остались у барышень теми же. То есть как раз имеет мето работа реверсированием диапазонов std::map.
Для вывода барышень в обратном порядке достаточно rbegin|rend.
Имею скафандр — готов путешествовать!
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Здесь вопрос не о включении абсолютно всего, так как стандартный алгоритм уже включен в библиотеку. То есть нужно лишь сделать так, чтобы std::map не остался не охваченным.
M>Ну, можно было бы ввести трансформирующие итераторы для работы с mapped values. Можешь написать в Спортлотосюда свои пожелания, и, быть может, их учтут в комитете по стандартизации (некоторые люди из комитета регулярно посещают данный ресурс).
С>>Впорос, как часто это надо, это чисто риторический вопрос.
M>Это существенный вопрос. Стандартная библиотека не резиновая, помещать туда всё подряд, как в Boost, не получится.
Здесь я с вами не соглашусь. Согласованность подхода значительно важнее понятия резиновости библиотеки. Для примера возьмем историю алгоритма copy_if, который, как известно, Страуструп в свое время выкинул из библиотеки. И что, это улучшило библиотеку? Нет коонечно! написать этот алгоритм самостоятельно достатоноч просто, но тем не менее это влекло к отсутствию общей семантики и согласованности библиотеки. А потому Страуструп признал свою ошибку, и copy_if, снова был включен в стандарт. На мой взгляд анналогичная ситуация имеет место и с reverse для std::map, но только ситуация еще хуже! так как 1) будет существовать многообразие реализаций этого алгоритма большее, чем оп сравнению с copy_if$ 2) появится многообразие названий этого алгоритма, так как если его назвать точно также, как reverse, то это буде т вводить в заблуждение, так как бдет путаница со стандартным алгоритмом.
Все эти вопросы были бы сняты, если функция reverese была бы членом класса.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>А на самом деле тут исходная позиция не в том, чтобы тащить все функции, которые возникают на практике, в иинтерфейс, а в том, что прерывается логическая последовательность использования стандартного алгоритма revrese. То есть он существукт, может применяться для контейнеров, а затем, бац!, обнаруживается, что имеется провал, и что этот алгоритм, который на самом деле имеет тот же самый семантический смысл, просто отсутствует!
С>>Я считаю это серьезным упущением стандарта.
J>Вот, понимаешь, прерывается логическая последовательность квадратного корня. Для 4 работает, для 3 — тоже, для 2 — работает, даже для 1 работает, и более того, даже для нуля! А затем, бац!, обнаруживается, что имеется провал и корень из -1 извлечь нельзя.
J>Я считаю это серьезным упущением теории действительных чисел.
Спасибо за развлечение. но когда у меня будет желание посмотреть на кривляние обезьянки, я лучше схожу в зоопарк!
Здравствуйте, Сыроежка, Вы писали:
С>А ключ и значение как раз и являются независимыми.
Привожу еще раз цитату из wikipediaна этот раз в более развернутом виде.
Внимание, читать медленно, вдумчиво, и если что-то не понятно, начать читать заново!
Ассоциативный массив (словарь) — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу
Т.е. std::map хранит в себе пары и позволяет находить и удалять среди них те, которые удовлетворяют условию равенства ключа внутри опять таки этих пар. Постарайтесь представить, что пара это единое целое, внутри которого содержится два поля: ключ и значение.
И далее пишут следующее:
Ассоциативный массив с точки зрения интерфейса удобно рассматривать как обычный массив, в котором в качестве индексов можно использовать не только целые числа, но и значения других типов — например, строки.
Т.е. для удобства его представляют как бы массив, но любой вменяемый с++ программист знает, что это не совсем так.
Так, во всех книжках обращают внимание, что за красивым и удобным интерфейсом вот такого использования:
m[key0] = value0;
скрывается следующая последовательность действий:
if( m.count(key0) )
{
m[key0] = value0;
}else{
m.insert( make_pair(key0, default_value) ); // т.е. для тяжелых типов не есть хорошо!
m[key0] = value0;
}
Но Вы конечно же это не читали, т.к. в это время уже бежали писать статью про std::map на Вашем любимом форуме.
С>Но в любом случае спасибо вам за участие. Я уже всю дискуссию подытожил в своем сообщении по адресу http://clipper.borda.ru/?1-6-0-00000022-000-0-0-1326309482 С>Почитайте, будет вам интересно. Я не думаю, что что-то принципиально новое вы сможете мне возразить. То есть я не вижу никаких серьезных контраргументов моей постановке вопроса.
Ничего интересного Вы там не пишите. Мне искренне жаль тех, кто решит познать с++ по Вашим статьям.
Кстати, "A map satisfies all of the requirements of a container, of a reversible container" означает, что у std::map имеется reverse_iterator, const_reverse_iterator, rbegin(), rend(). И совсем не обязан иметь средство реверсивного расположения значений элементов! Вы бы хотя бы стандарт открыли что-ли!? И вообще курите поменьше ту дрянь, что дает Вам возможность думать настолько обобщенно и концептуально..
P.S. Когда в следующий раз захотите выпендриться на своем форуме за счет Саттера, хотя бы прочитайте ВНИМАТЕЛЬНО то, что он пишет, например комменты к коду. Если не поняли с первого раза, читайте пока не дойдет, а уже потом пишите статьи, про то, какой Вы умный!
Re[16]: Разместить в обратном порядке отображаемые значения
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, rumit7,
С>>Я вам настоятельно рекомендую почитать книгу Скотта Майерса "Эффективное использование STL" в частнсти его совет 23 "Используйте возможность замены ассоциативных контейнеров сортированными векторами", и тогда вы поймете, что между веторами и ассоциативными контейнерами существует неформальная связь. С>>То есть прежде чем цитировать мне банальные вещи, вы постарайтесь понять суть этих контейнеров и неформальную связь между ними, и тогда вы поймете смысл поставленной мною проблемы.
R>Спорить с Вами безполезное занятие, т.к. любой аргумент, будь то высказывание Майерса, Саттера или цитата из стандарта Ваш больной мозг трактует как подтверждение Вашей гениальности!
R>За сим спрошу прямо — что за травку курим?
Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает. То есть я вообще мог здесь не распинатьсяы, а указать просто на то, что стандарт не выполняет своих обязательств. То есть он был по крайней мере в разделе стандартных алгоритмов для этого алгоритма указать все исключения его применения, если основные требования выполнены, такие, как, например, наличие двустороннего итератора. Но этого нет. Этого вполне достатончо, чтобы заявить, что стнадарт содержит серьезные упущения.
А на самом деле проблема решается очень просто. В стандарте должна быть форма этого алгоритма вида
void reverse( BidirectionalIterator first,
BidirectionalIterator last,
BinaryPredicate binary_predicate );
и тогда никаких пролблем с коонтейнером std::map не было бы. К этому я и хотел подвести дискуссиию. Но оказалось, что уровень понимания вопроса настолько низок у аудитории, что бесполезно рассуждать на подобные темы.
Здравствуйте, Сыроежка, Вы писали:
C>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap?
pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, Igore, Вы писали:
I>>Здравствуйте, Сыроежка, Вы писали:
I>>>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>>>Так сложности нет и в том, чтобы написать все стандартные алгоритмы! I>>Раз нет сложности, то напиши и используй.
С>>>Только зачем каждый раз это делать, вы можете объяснить? I>>Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>>>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>>>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
I>>Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит. I>>Даже если вас съели, у вас как минимум два выхода.
С>Вызнаете разницу между тем, что алгоритм присутствует в стандарте, и во всех проектах используется этот алгоритм, и тем, что в каждом команда разрабатывает свой алгоритм?
Повторю еще раз, то что тебе написали, пиши в комитет с просьбой включения в стандарт нового алгоритма. Или создай свою STL с блэкджеком и ну ты понял, разрекламируй ее и может она станет еще одним de facto, как буст, можешь туда попробовать добавить свои идеи
С>В том-то и проблема, что как раз в стандарте не хватает той формы алгоритма, которую я здесь уже привел. Она органически всотребована для многих задач. Даже если рассмотреть аткую простую задачу, как если бы вектор хранилл в качестве элементов некую структуру, и нужно реверсировать не целиком всю структуру, а лишь некоторые ее поля, то уже возникает сложность, так как нет подходящего средства!
Тебе уже несколько раз объясняли, я повторю, map<int, int> = vector<pair<const int, int>>, тогда reverse это просто обход в обратном порядке, так как лезть во внутренее устройства map мы не можем.
С>реверсировать не целиком всю структуру, а лишь некоторые ее поля
Это трансформация а не реверсирование.
Реверсирование просто и понятно, а тебе хочется немного другого, я бы на твоем месте сменил тип контейнера и не мучился
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
J>>>Тебе придется написать такого рода специальные версии всех остальных алгоритмов, которые полагаются на swap (а в С++11 — еще и move). J>>>random_shuffle, например, да и sort туда же.
С>>Пока что достаточно хотя бы добавить новую форму для reverse. Это уже было бы прогрессом и решало множество задач, которые без наличия такой формы алгоритма решить не просто.
J>Абсолютно недостаточно. Как только ты включишь эту версию reverse в стандарт, тут же появится Сыроежка2, который объявит отсутствие аналогичных версий всех остальных обменивающих алгоритмов "существенным упущением стандарта". Так что либо все, либо ничего.
Я вам больше скажу, у мен только версий алгоритма for_each около 20, если мне память не изменяет. И я не виижу причин не включить их в стандарт. напротив, в своей рпактике я всегда сталкивался с ненужными ограничениями и изобретением велосипеда.
Сами подумайте, например, насколько бы был полезен алгоритм for_each_if
ксати сказать, вы забыли, что в стандарт включены такие примитивные алгоримты, как all_of и any_of. Так что помимо Сыроежек хватает и других программистов!
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, Сыроежка, Вы писали:
С>>Проблема в том, что в стандарте нет такого адаптера итератора. M>Я не утверждал что есть, я лишь предложил STL way решение.
С>> Поэтому лучше ввести форму этого алгоритма с предикатом. Тогда не только можно использовать с контейнером sttd::map, но и решать задачи, когда для последовательного контейнера нужно реверсировать не весь элемент целиком, а, допустим, его подчлены. То есть, например, если у вас элементом является некоторая структуру, то нужно реверсировать не всю структуру, а лишь отдельные ее члены. M>Не лучше. Универсальнее использовать адапторы итераторов которые могут ссылаться на class members.
С>>Сейчас эту задачу даже для последовательного контейнера нельзя решить с помощью стандартного аллгоритма, так как у пользователя нет возможности управлять его работой. Ежели появится форма этого алгоритма с предикатом, то пользователь в предикате может задавать требуемые операции.
M>Порассуждайте не над возможностью , а над целесообразностью.
Разыменованный адаптер итератора может ссылаться лишь на одно данное. Поэтому ваше предложение крайне ограниченное. А использование предиката и использование стандартного итератора контейнера делает решение задачи прозрачной.
Здравствуйте, SleepyDrago, Вы писали:
SD>Предлагаю банить в /forum/cpp/* по слову клиппер в сообщении за необратимое поражение мозга оным клиппером.
Да его за оверквотинг тут уже с полтора десятка раз банхаммером приложить следовало.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Разместить в обратном порядке отображаемые значения std::map
Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
Здравствуйте, Сыроежка, Вы писали:
С>Спасибо за пример. Но я наверное нечетко сформулировал свой исходный вопрос. Меня удивило, что в контейнере std::map нет функции-члена reverse Естественно я сделал предположение, что если такой функции-члена класса нет, то наверное легко эту операцию сделать с помощью стандартных алгоритмов. но стандартный алгоритм std::reverse по понятным причинам не подходит. С>Поэтому и возник вопрос, как с помощью стандартных алгоритмов сделать подобную операцию для std::map. Может быть в boost такой алгоритм существует, если с помощью стандартных алгоритмов нужно исхитряться?
Задача не совсем понятна, но попробую отгадать. Вариант 1 — надо что-то сделать с элементами в обратном порядке
С>Поэтому и возник вопрос, как с помощью стандартных алгоритмов сделать подобную операцию для std::map. Может быть в boost такой алгоритм существует, если с помощью стандартных алгоритмов нужно исхитряться?
ну есть там transform_iterator, но он какой-то замороченый
что-нибудь в таком стиле
struct MyTransform
{
//здесь еще какая-то возня с тайпдефами должна быть
MyValue& operator()(std::pair<MyKey,MyValue>& keyValue) const { key.second; }
};
std::reverse(boost::make_transform_iterator(map.begin(), MyTransform() ),boost::make_transform_iterator(map.end(), MyTransform() ));
можно конечно попробовать MyTransform заменить на
bind( &std::map<...>::value_type::second, _1 )
или
[](std::map<...>::value_type& pair) { return pair.second;});
по мне так все это выглядит одинаково мерзко и нечитабельно, даже если будет работать
Re[4]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, Сыроежка, Вы писали:
С>>Спасибо за пример. Но я наверное нечетко сформулировал свой исходный вопрос. Меня удивило, что в контейнере std::map нет функции-члена reverse Естественно я сделал предположение, что если такой функции-члена класса нет, то наверное легко эту операцию сделать с помощью стандартных алгоритмов. но стандартный алгоритм std::reverse по понятным причинам не подходит. С>>Поэтому и возник вопрос, как с помощью стандартных алгоритмов сделать подобную операцию для std::map. Может быть в boost такой алгоритм существует, если с помощью стандартных алгоритмов нужно исхитряться?
M>Задача не совсем понятна, но попробую отгадать. M>Вариант 1 — надо что-то сделать с элементами в обратном порядке M>
M>Вариант 2 — сделать map с обратным порядком — M>Тут надо просто компаратор другой для второго map'а задать.
M>Но вообще, это вроде очевидные решения, я наверно задачи не понял.
Задача простая: для заданного контейнера std::map реверсировать отображаемые значения.
Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map. Если он не включен, то наверное предполагается, что сделать это просто с помощью стандартных алгоритмов. Ведь какие основные принципы включения или не включения алгоритмов к ачестве функций-членов контейнеров? Первое- это невозможность сделать данную операцию с помощью стандартного алгоритма. например, стандартный алгоритм std::sort требует наличия итераторов произвольного доступа. Так как в контейнере std::list итератор не является итератором произвольного доступа, то этот алгоритм включили в качестве функции-лена класса для контейнера std::list Второе — это если делать алгоритм членом класса, то можно достичь большей эффективности. Такие алгоритмы включены, например, в класс std::basic_string.
Поэтому и возник вопрос, раз алгоритм reverse не включен в контейнер std::map в качестве члена класса, то наверное его можно как-то достаточно просто реализовать с помощью стандартных алгоритмов? да причем так, чтобы каждый программист не открывал для себя заново велосипед.
>> Как проще выполнить реверсию значений элементов для заданного контейнера >> std::map? То есть ключи остаются на месте, а меняются в обратном порядке
MZ>Порядок хранения элементов в std::map не определён. Обратным порядком для MZ>неоределённого порядка будет также неопределённый порядок. Следовательно, MZ>тебе ПРОСТО НЕ НУЖНО НИЧЕГО ДЕЛАТЬ.
Ты что-то путаешь. Порядок на множестве ключей определен и этот порядок для множества ключей данного экземпляра std::map изменить нельзя.
Re[5]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения.
если я правильно понял, то хочется из одного словаря сделать второй, у которого ключи будут старыми, а значения переставятся
первый же ответ rm822 дал хороший способ совершить данное действо (вариант inplace)
С>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
1) лично мне никогда такое не требовалось, поэтому предположу, что задача не распространена, поэтому ее никто не просил
2) данный частный алгоритм реализуем штатными средствами (отсылаю к тому же rm822)
С>Второе — это если делать алгоритм членом класса, то можно достичь большей эффективности. Такие алгоритмы включены, например, в класс std::basic_string.
не очень представляю какие такие внутренние данные контейнера смогут помочь ускорить предложенный выше алгоритм, не ухудшив другие характеристики std::map. мне кажется он вполне себе оптимальным
для варианта, когда исходный словарь не меняется, а создается его копия можно было бы достичь лучшей производительности, скопировав внутреннее дерево, т.к. при этой операции форма дерева не меняется. меняются лишь ассоциированные данные. однако такими алгоритмами редко балуются из-за накладных расходов (immutable approach не в почете нынче)
С>Поэтому и возник вопрос, раз алгоритм reverse не включен в контейнер std::map в качестве члена класса, то наверное его можно как-то достаточно просто реализовать с помощью стандартных алгоритмов? да причем так, чтобы каждый программист не открывал для себя заново велосипед.
на велосипедах весь си++ и живет
Re[6]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Marty, Вы писали:
M>Здравствуйте, Сыроежка, Вы писали:
С>>Задача простая: для заданного контейнера std::mapреверсировать отображаемые значения. M>Таки расскажите, что значит реверсировать7
С>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map. Если он не включен, то наверное предполагается, что сделать это просто с помощью стандартных алгоритмов. Ведь какие основные принципы включения или не включения алгоритмов к ачестве функций-членов контейнеров? Первое- это невозможность сделать данную операцию с помощью стандартного алгоритма. например, стандартный алгоритм std::sort требует наличия итераторов произвольного доступа. Так как в контейнере std::list итератор не является итератором произвольного доступа, то этот алгоритм включили в качестве функции-лена класса для контейнера std::list Второе — это если делать алгоритм членом класса, то можно достичь большей эффективности. Такие алгоритмы включены, например, в класс std::basic_string. С>>Поэтому и возник вопрос, раз алгоритм reverse не включен в контейнер std::map в качестве члена класса, то наверное его можно как-то достаточно просто реализовать с помощью стандартных алгоритмов? да причем так, чтобы каждый программист не открывал для себя заново велосипед.
M>map уже сортирован по ключу. итераторов произвольного доступа нет, и, имхо, не будет, если и будут, то с временем доступа O(N).
M>и задача "реверсировать" так и не раскрыта.
Так я в первом своем сообщении, и как мне представляется, в других сообщениях, ясно сказал, что реверсировать нужно отображаемые значения, то есть mapped_type, сохранив порядок ключей.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, Сыроежка, Вы писали:
С>>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения. U>если я правильно понял, то хочется из одного словаря сделать второй, у которого ключи будут старыми, а значения переставятся U>первый же ответ rm822 дал хороший способ совершить данное действо (вариант inplace)
С>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map. U>1) лично мне никогда такое не требовалось, поэтому предположу, что задача не распространена, поэтому ее никто не просил U>2) данный частный алгоритм реализуем штатными средствами (отсылаю к тому же rm822)
С>>Второе — это если делать алгоритм членом класса, то можно достичь большей эффективности. Такие алгоритмы включены, например, в класс std::basic_string. U>не очень представляю какие такие внутренние данные контейнера смогут помочь ускорить предложенный выше алгоритм, не ухудшив другие характеристики std::map. мне кажется он вполне себе оптимальным U>для варианта, когда исходный словарь не меняется, а создается его копия можно было бы достичь лучшей производительности, скопировав внутреннее дерево, т.к. при этой операции форма дерева не меняется. меняются лишь ассоциированные данные. однако такими алгоритмами редко балуются из-за накладных расходов (immutable approach не в почете нынче)
С>>Поэтому и возник вопрос, раз алгоритм reverse не включен в контейнер std::map в качестве члена класса, то наверное его можно как-то достаточно просто реализовать с помощью стандартных алгоритмов? да причем так, чтобы каждый программист не открывал для себя заново велосипед. U>на велосипедах весь си++ и живет
Да, вы правильно поняли задачу. Только изменение надо делать "на месте", не создавая второй контейнер.
Что касается первого предложенного варианта, то как раз он меня не устраивает, так как лично бы я сделал по-другому. например, можно не использовать для цикла размер контейнера. Второе — можно не использовать два типа итераторов в цикле, а воспользоваться одним типом итератора, так как он заведомо двусторонний и т.д. То есть получается, что у каждого программиста будет свое решение, и не обязательно корректное. Например, в алгоритме reverese (в его стандартной реализации) можно легко допустить оишбку, когда итератор, идущий от начала, "перескакивает итератор, идущий от конца последовательности. То есть не будет выполнено условие цикла. Это я к тому, что чем больше дается свободы в реализации алгоритма, тем больше вероятномть наличия ошибки в реализации. То есть получается, что каждый программист изобретает велосипед заново. Кроме того у такого доморощенного алгоритма могут быть разные названия, а потому для читающего код сразу будет трудно понять, а что именно эта функция делает, так как в разных проектах она будет называться поо-разному. То есть за названием функции не будет угадываться ее семантика. А это на мой взгляд существенный недостаток.
Любой стандартный алгоритм должен охватывать как можно больше типов контейнеров. И даже если у контейнера имеется собственная аналогичная функция-член, как, например, для контейнера std::basic_string функция-член find, стандартный алгоритм также желательно в общем случае должен работать с таким контейнером.
Здравствуйте, baily, Вы писали:
B>Здравствуйте, andy1618, Вы писали:
A>>Здравствуйте, Сыроежка, Вы писали:
С>>>Меня удивило, что в контейнере std::map нет функции-члена reverse
A>>Тут ничего удивительного нет. std::map — это ассоциативный массив (ключ-значение), работа с которым предполагается как с фиксированными парами с доступом по ключу. A>>Более того, в некоторых языках программирования ассоциативные массивы реализуются как хеш-таблицы, где вообще понятие "порядок ключей" не имеет смысла. A>>Подробности можно почитать здесь.
B>Непонятно, почему заминусовали данный ответ. Ну, конечно, можно придраться, что порядок элементов в map зависит от ключа и это иногда нужно. B>Однако операции для map, которые переставляют значения для ключей типа reverse, уж совершенно лишены смысла. Ведь это совсем не то, что перебрать элементы B>через rbegin, rend а совсем другое. Ясно, что такую задачу, когда это полезно придумать можно, но это не отвечает тому, для чего задумывался map. B>С таким же основанием можно было бы потребовать добавить функции-член для подсчета среднего гармонического значения от элементов контейнера и т.д. и т.п
Скажу сразу, лично я ничего не минусовал!
Но я совершенно не согласен с вашим утверждением. Реверсирование данных любого контейнера — это очень полезная вещь. например, даже в базах данных, имеющих доступ к записям по ключу, часто требуется создавать реверсивный набор, чтобы выполнить ту или иную задачу.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
J>Зачем? J>Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
Я вас уверяю, что задачи, возникающие на практике. значительно разнообразнее, чем может представить ваша фантазия в данный момент!
Здравствуйте, baily, Вы писали:
B>Непонятно, почему заминусовали данный ответ. Ну, конечно, можно придраться, что порядок элементов в map зависит от ключа и это иногда нужно.
std::map — это не просто какой-то там ассоциативный контейнер, это контейнер, предоставляющий некие гарантии по сложности операций, по интерфейсу и по семантике
крайне интересным считаю документацию контейнеров от SGI : http://www.sgi.com/tech/stl/Map.html
там формально введена некая классификация контейнеров и вы можете убедиться, что std::map удовлетворяет моделям Unique Sorted Associative Container, Pair Associative Container
именно подобные модели позволяют для конкретно этого контейнера реализовывать алгоритмы, которые не прикрутишь к другим ассоциативным контейнерам типа хеш-таблиц
в частности, алгоритм ТС применим к std::map и не применим к хеш-таблицам, потому что там нет порядка ключей
B>Однако операции для map, которые переставляют значения для ключей типа reverse, уж совершенно лишены смысла.
операция не лишена смысла, в ней заинтересован ТС и уже дали даже один вариант реализации
Re[5]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения. С>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
Потому что эта операция в общем случае неосмысленна.
Re[4]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>Здравствуйте, Сыроежка, Вы писали:
С>>>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
J>>>Зачем? J>>>Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
С>>Я вас уверяю, что задачи, возникающие на практике. значительно разнообразнее, чем может представить ваша фантазия в данный момент!
J>Этот комментарий, безусловно, всё прояснил, и главное, ответил на вопрос "зачем".
На самом деле ваш аргумент вообще не состоятелен. Так как с таким же успехом можно сказать, что алгоритм reverse вообще не нужен ни для вектором, ни для списков, так как можно работать с обратными итераторами. Но тем не менее такой алгоритм существуетт, а значит существуют задачи, где он необходим.
Здравствуйте, Сыроежка, Вы писали:
С>На самом деле ваш аргумент вообще не состоятелен. Так как с таким же успехом можно сказать, что алгоритм reverse вообще не нужен ни для вектором, ни для списков, так как можно работать с обратными итераторами. Но тем не менее такой алгоритм существуетт, а значит существуют задачи, где он необходим.
Какой аргумент? Что для обратного обхода есть итераторы и надо пользоваться ими, благо скорость одна и та же будет? Ну так это же медицинский факт
Ну и я задачу так и не услышал. Реальную задачу, а не то, как ты ее пытаешься решить при помощи std::map, требуя реверса.
Вряд ли ведь задача ставится в терминах мапа и ключей-значений, правда?
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, Сыроежка, Вы писали:
С>>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения. С>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
C>Потому что эта операция в общем случае неосмысленна.
Не говорите "гоп" пока не перепрыгнули! Это для вас она сейчас является неосмысленной, потому что вы не в состоянии сейчас что-то придумать. А практика показывает, что существующие задачи настолько разнообразны, что не хватит никакой фантазии человека, чтобы представить все задачи, с которыми стаокивается программист!
Кстати сказать, сейчас пришла забавная аналогия с конкурсом красоты среди женщин. Каждая претендентка имеет свой заранее определенный порядковый номер. Они так и выходят на сцену с прикрепленными сбоку номерами. Но после каждого выступления претенденток жюри переставляет барышень в соответствии с набранными очками за красоту или за еще какой-то показатель. То есть говорят: "Вы поменяйтесь местами, и вы поменяйтесь местами". И на следующем этапе конкурса барышни выходят на сцену именно в том порядке, как их жюри поменяла, хотя исходные номера остались у барышень теми же. То есть как раз имеет мето работа реверсированием диапазонов std::map.
The fundamental property of iterators of associative containers is that they iterate through the containers in the non-descending order of keys where non-descending is defined by the comparison that was used to construct them.
(c) Стандарт
Как много веселых ребят, и все делают велосипед...
Re[7]: Разместить в обратном порядке отображаемые значения s
С>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
Ответ вас видимо удивит, но все же: по определению.
Re[6]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, baily, Вы писали:
С>Но я совершенно не согласен с вашим утверждением. Реверсирование данных любого контейнера — это очень полезная вещь. например, даже в базах данных, имеющих доступ к записям по ключу, часто требуется создавать реверсивный набор, чтобы выполнить ту или иную задачу.
Я согласен, что реверсирование данных это очень полезная вещь, но, если вам нужно то, что предложили здесь
, то это не реверсирование,
так как данная операция переставляет не элементы контейнера, которые есть пары ( ключ, значение ), а переставляет только значения, оставляя ключи на местах.
То есть при таком реверсировании элементы контейнера меняются!!! И вот данная операция не очень полезна.
Настоящее же реверсирование map — это получение контейнера нового типа, у которого функция сравнения ключей имеет противоположный смысл.
Реализовать тоже не сложно.
Re[3]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
С>>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
J>>Зачем? J>>Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
С>Я вас уверяю, что задачи, возникающие на практике. значительно разнообразнее, чем может представить ваша фантазия в данный момент!
Не нужно тащить в интерфейс библиотечного класса все функции, которые возникают на практике.
Re[5]: Разместить в обратном порядке отображаемые значения s
Сыроежка:
С>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
Насколько часто нужна такая операция? Стандартная библиотека не может включать в себя абсолютно всё. Она даёт некую базовую наиболее часто используемую функциональность и предоставляет возможность эту базовую функциональность расширять. Так всегда было и так будет дальше.
Реализовать такой алгоритм ручками несложно:
#include <utility>
template <class MapIterator>
void reverse_mapped_values(MapIterator first, MapIterator ending)
{
for (;;)
if (first == ending || first == --ending)
return;
else
{
using std::swap;
swap(first->second, ending->second);
++first;
}
}
IMHO, в стандартной библиотеки есть куда более неприятные пробелы — например, отсутствие у файловых потоков конструктора, принимающего имя файла в юникоде (что для меня во многих случаях делает такие потоки бесполезными).
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Кстати сказать, сейчас пришла забавная аналогия с конкурсом красоты среди женщин. Каждая претендентка имеет свой заранее определенный порядковый номер. Они так и выходят на сцену с прикрепленными сбоку номерами. Но после каждого выступления претенденток жюри переставляет барышень в соответствии с набранными очками за красоту или за еще какой-то показатель. То есть говорят: "Вы поменяйтесь местами, и вы поменяйтесь местами". И на следующем этапе конкурса барышни выходят на сцену именно в том порядке, как их жюри поменяла, хотя исходные номера остались у барышень теми же. То есть как раз имеет мето работа реверсированием диапазонов std::map.
Э, нет, батенька. Теперь понятно происхождения вашей путаницы.
Тут имеется два параметра :
1) "Исходный номер" барышни, по сути ее числовой идентификатор
2) "Порядковый номер" барышни в туре
Для представления всех девушек можно использовать map с ключом равным "Исходный номер".
А вот для представления девушек в каждом туре надо использовать vector из их исходных номеров.
Положение в этом vector и будет текущим "Порядковым номером"
Re[6]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
M>Насколько часто нужна такая операция? Стандартная библиотека не может включать в себя абсолютно всё. Она даёт некую базовую наиболее часто используемую функциональность и предоставляет возможность эту базовую функциональность расширять. Так всегда было и так будет дальше.
M>Реализовать такой алгоритм ручками несложно:
M>
M>IMHO, в стандартной библиотеки есть куда более неприятные пробелы — например, отсутствие у файловых потоков конструктора, принимающего имя файла в юникоде (что для меня во многих случаях делает такие потоки бесполезными).
Здесь вопрос не о включении абсолютно всего, так как стандартный алгоритм уже включен в библиотеку. То есть нужно лишь сделать так, чтобы std::map не остался не охваченным. Потому что в противном случае возникают вопросы и сложности и несогласованность кода.
Впорос, как часто это надо, это чисто риторический вопрос. Например, в своей программе вы можете воообще не исаользовать ни одного стандартного алгоритма. Следует ли из этого, что все алгоритмы надо исключить из стандартной библиотеки? А ответьте мне на вопрос, как часто вы в свооих проектах использовали стандартные алгоритмы для перестановок?!
По поводу того, что можно написать код "своими ручками", то я уже по этому поводу достаточно ясно ответил, что это не удовлетворительное решение, когда стандартную оперрацию каждый программист пишет своими ручками.
Здравствуйте, baily, Вы писали:
B>Здравствуйте, Сыроежка, Вы писали:
С>>Кстати сказать, сейчас пришла забавная аналогия с конкурсом красоты среди женщин. Каждая претендентка имеет свой заранее определенный порядковый номер. Они так и выходят на сцену с прикрепленными сбоку номерами. Но после каждого выступления претенденток жюри переставляет барышень в соответствии с набранными очками за красоту или за еще какой-то показатель. То есть говорят: "Вы поменяйтесь местами, и вы поменяйтесь местами". И на следующем этапе конкурса барышни выходят на сцену именно в том порядке, как их жюри поменяла, хотя исходные номера остались у барышень теми же. То есть как раз имеет мето работа реверсированием диапазонов std::map.
B>Э, нет, батенька. Теперь понятно происхождения вашей путаницы.
B>Тут имеется два параметра : B>1) "Исходный номер" барышни, по сути ее числовой идентификатор B>2) "Порядковый номер" барышни в туре
B>Для представления всех девушек можно использовать map с ключом равным "Исходный номер". B>А вот для представления девушек в каждом туре надо использовать vector из их исходных номеров. B>Положение в этом vector и будет текущим "Порядковым номером"
Не вижу никакого смысла усложнять объем данных, создавая еще вектор. Достаточно иметь один контейнер, в котором по мере необходимости перставлять значения элементов.
Здравствуйте, Анатолий Широков, Вы писали:
С>>Вопрос состоит в другом, почему для контейнера map не применим и не существует алгоритм reverse. Ведь на самом деле не обязательно переставлять весь набор элементов. Может, например, потребоваться перестановканекоторого поддиапазона набора элементов и т.д.
АШ>Ответ вас видимо удивит, но все же: по определению.
Сыроежка:
С>Здесь вопрос не о включении абсолютно всего, так как стандартный алгоритм уже включен в библиотеку. То есть нужно лишь сделать так, чтобы std::map не остался не охваченным.
Ну, можно было бы ввести трансформирующие итераторы для работы с mapped values. Можешь написать в Спортлотосюда свои пожелания, и, быть может, их учтут в комитете по стандартизации (некоторые люди из комитета регулярно посещают данный ресурс).
С>Впорос, как часто это надо, это чисто риторический вопрос.
Это существенный вопрос. Стандартная библиотека не резиновая, помещать туда всё подряд, как в Boost, не получится.
Re[4]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, baily, Вы писали:
B>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>Здравствуйте, Сыроежка, Вы писали:
С>>>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
J>>>Зачем? J>>>Если затем, чтоб обходить в обратном порядке, то есть rbegin/rend.
С>>Я вас уверяю, что задачи, возникающие на практике. значительно разнообразнее, чем может представить ваша фантазия в данный момент!
B>Не нужно тащить в интерфейс библиотечного класса все функции, которые возникают на практике.
А на самом деле тут исходная позиция не в том, чтобы тащить все функции, которые возникают на практике, в иинтерфейс, а в том, что прерывается логическая последовательность использования стандартного алгоритма revrese. То есть он существукт, может применяться для контейнеров, а затем, бац!, обнаруживается, что имеется провал, и что этот алгоритм, который на самом деле имеет тот же самый семантический смысл, просто отсутствует!
Я считаю это серьезным упущением стандарта. То есть я с самого начала считал, что это недостаток стандарта, но думал, задавая вопрос, что можетт быть существует давно очень простой, а самое главное общепринятый метод, как выполнить этот алгоритм для std::map, а я просто этот банальный метод не знаю. И поэтому хотел проверить, существуетт ли такой метод, или нет. Оказалось, что на самом деле такого общепринятого и де-факто стандартного метода нет! То есть поступают различные предлоежния, как этот сделать, со многими из которых я не соогласен и сделал бы это по-другому. А это значит имеет место несогласовнность в реализации стандартного алгоритма. То есть имеет место серьезный пробел в согласованности использования алгоритма.
Здравствуйте, baily, Вы писали:
B>Э, нет, батенька. Теперь понятно происхождения вашей путаницы.
B>Тут имеется два параметра : B>1) "Исходный номер" барышни, по сути ее числовой идентификатор B>2) "Порядковый номер" барышни в туре
B>Для представления всех девушек можно использовать map с ключом равным "Исходный номер". B>А вот для представления девушек в каждом туре надо использовать vector из их исходных номеров. B>Положение в этом vector и будет текущим "Порядковым номером"
Здравствуйте, Сыроежка, Вы писали:
С>А на самом деле тут исходная позиция не в том, чтобы тащить все функции, которые возникают на практике, в иинтерфейс, а в том, что прерывается логическая последовательность использования стандартного алгоритма revrese. То есть он существукт, может применяться для контейнеров, а затем, бац!, обнаруживается, что имеется провал, и что этот алгоритм, который на самом деле имеет тот же самый семантический смысл, просто отсутствует!
С>Я считаю это серьезным упущением стандарта.
Вот, понимаешь, прерывается логическая последовательность квадратного корня. Для 4 работает, для 3 — тоже, для 2 — работает, даже для 1 работает, и более того, даже для нуля! А затем, бац!, обнаруживается, что имеется провал и корень из -1 извлечь нельзя.
Я считаю это серьезным упущением теории действительных чисел.
Сыроежка:
С>Для примера возьмем историю алгоритма copy_if
В комитете по стандартизации не хватает людских ресурсов для тщательной проверки правил. И copy_if тому наглядный пример: LWG DR 2039. Issues with std::reverse and std::copy_if.
С>На мой взгляд анналогичная ситуация имеет место и с reverse для std::map
Интересно, а чем алгоритм reverse такой особенный? Если вдруг захочется скопировать куда-то mapped значения, удовлетворяющие некоему условию, то ты тогда предложишь ещё copy_if в std::map добавить? По-моему, если тут что-то и добавлять, так это не reverse в map, а функции (или шаблоны функций) для получения итераторов, указывающих на mapped values. Использование такого добра выглядело бы либо так:
Здравствуйте, Сыроежка, Вы писали:
С>Не просветите меня, с каких это пор список не поддерживает свою организацию хранения данных?! Как раз каждый контейнерсуществует самостоятельно именно из-за того, что поддерживает собственную организацию хранения данных.
Перечитай мое сообщение еще раз, там речь шла о поддержании отсортирвоанности, а не об организации хранения.
С>Что касается всего остального, то это говорит, что вы не в состоянии мыслить концептуально. Вы относитеьс к тем людям, которые не в состоянии обощать, а постоянно решаете частные вопросы. Для программиста — это серьезный недостаток. Я вам советую исправлять его!
Вы относитесь к людям, которые не в состоянии прочитать внимательно то, что написано. Для программиста — это серьезный недостаток.
А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Для примера возьмем историю алгоритма copy_if
M>В комитете по стандартизации не хватает людских ресурсов для тщательной проверки правил. И copy_if тому наглядный пример: LWG DR 2039. Issues with std::reverse and std::copy_if.
С>>На мой взгляд анналогичная ситуация имеет место и с reverse для std::map
M>Интересно, а чем алгоритм reverse такой особенный? Если вдруг захочется скопировать куда-то mapped значения, удовлетворяющие некоему условию, то ты тогда предложишь ещё copy_if в std::map добавить? По-моему, если тут что-то и добавлять, так это не reverse в map, а функции (или шаблоны функций) для получения итераторов, указывающих на mapped values. Использование такого добра выглядело бы либо так:
M>
Дело в том, что алгоритм reverse сохраняет свое семантическое значение и для std::map. Что такое reverse? Это, фактически, обобщение swap для более, чем двух элементов.
Что касается copy_if, у него есть по крайней мере возможная альтернатива в виде transform с предикатом, с помощью которого можно создавать новые последовательности. У reverse даже близко нет какоой-то альтернативы, так как нужно получать сразу же два значения последовательности для обработки? одно — из начала последовательности, другое — из конца последовательнсоти. То есть нет такого алгоритма, который поставлял бы в предикат такую пару итераторов.
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Для примера возьмем историю алгоритма copy_if
M>В комитете по стандартизации не хватает людских ресурсов для тщательной проверки правил. И copy_if тому наглядный пример: LWG DR 2039. Issues with std::reverse and std::copy_if.
С>>На мой взгляд анналогичная ситуация имеет место и с reverse для std::map
M>Интересно, а чем алгоритм reverse такой особенный? Если вдруг захочется скопировать куда-то mapped значения, удовлетворяющие некоему условию, то ты тогда предложишь ещё copy_if в std::map добавить? По-моему, если тут что-то и добавлять, так это не reverse в map, а функции (или шаблоны функций) для получения итераторов, указывающих на mapped values. Использование такого добра выглядело бы либо так:
M>
Можно еще посмотреть с другой стороны. Фактически, к std::map можно относиться как к некоторой частной разновидности более общего подхода к контейнеру наравне с std::vector. То есть первая разновидность позволяет обращаться к элементам контейнера по ключу, вторая разновидность позволяет обращаться к элементам контейнера, когда клюом является индекс элемента. Ведь в принципе числа натурального ряда также моогут быть взяты в качестве ключа. Если мы создадим контейнер std::map с ключами 0, 1, 2, и т.д., то обращение к данным, хранимым в sttd::map, не будет отличаться от обращения к данным, хранимым в std::vector, То есть концептуально имеется один тип контейнера, у которого могут быть различные ключи в том числе и чсила натурального ряда. Но получается, что в одном частном случае, коогда ключами являются числа натурального ряда, мы можем применять функцию reverse к некоторому диапазону элементов контейнера, а во втором случае мы этого делать не можем. Происходит семантический разрыв и не согласованность интерфейса..
Здравствуйте, rus blood, Вы писали:
RB>Здравствуйте, Сыроежка, Вы писали:
С>>Спасибо за развлечение. но когда у меня будет желание посмотреть на кривляние обезьянки, я лучше схожу в зоопарк!
RB>Смотри пункт 5
Вы этот пункт покажите для автора предудыщего сообщения. Надо конструктивно обсуждать вопрос, а не заниматься поясничаньем. Иначе любую тему можно превратить в профонацию! Так что будьте объективны. Иначе как окликнется, так и аукнется!
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Не просветите меня, с каких это пор список не поддерживает свою организацию хранения данных?! Как раз каждый контейнерсуществует самостоятельно именно из-за того, что поддерживает собственную организацию хранения данных. J>Перечитай мое сообщение еще раз, там речь шла о поддержании отсортирвоанности, а не об организации хранения.
С>>Что касается всего остального, то это говорит, что вы не в состоянии мыслить концептуально. Вы относитеьс к тем людям, которые не в состоянии обощать, а постоянно решаете частные вопросы. Для программиста — это серьезный недостаток. Я вам советую исправлять его! J>Вы относитесь к людям, которые не в состоянии прочитать внимательно то, что написано. Для программиста — это серьезный недостаток.
J>А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
Вы просто не понимаете, что вектор можно рассматривать как отсортированный контейнер, ключом которого является индекс элемента! Создайте std::map с ключом, равным числам натурального ряда последовательно, например, от 0 до 99, и фактически, ваш контейнер будет представлять собой вектор! Только и всего! То есть можно концептуально рассматривать вектор, как некоторый частный случай std::map (раз вы не ведете речь о физической организации, а говорите лишь об отсортированности по ключу), в котором ключем является индекс элемента!
например, рассмотрите код, чтобы было вам понятно
Фактически здест имеют место быть пары { ключ, значение }, где ключом является индекс элемента. Причем последовательность априори отсортирована по индексу элемента!
> MZ>Порядок хранения элементов в std::map не определён. Обратным порядком для > MZ>неоределённого порядка будет также неопределённый порядок. Следовательно, > MZ>тебе ПРОСТО НЕ НУЖНО НИЧЕГО ДЕЛАТЬ. > > Ты что-то путаешь. Порядок на множестве ключей определен и этот порядок для
Определён порядок на ключах. И порядок итерирования. Порядок хранения -- не
определён.
Posted via RSDN NNTP Server 2.1 beta
Re[6]: Разместить в обратном порядке отображаемые значения s
> алгоритмы, которые не прикрутишь к другим ассоциативным контейнерам типа хеш-таблиц > в частности, алгоритм ТС применим к std::map и не применим к хеш-таблицам, > потому что там нет порядка ключей
Порядок ключей хеш-таблицы может быть и задан как-то.
Но это не отменяет сделанных выводов.
Posted via RSDN NNTP Server 2.1 beta
Re[7]: Разместить в обратном порядке отображаемые значения s
On 01/11/2012 05:03 PM, Сыроежка wrote: > койтесь, как я уже сказал, мир реальных задач значительно богаче вашей фантазии, > что вам даже и не снилось, какие задачи могут встретиться на практике. Я вам уже > сказал, что ваш аргумент не состоятелен, так как согласно ему, вообще непонятно, > зачем существует этот алгоритм, например, для векторов?
Для векторов как раз всё понятно, зачем этот алгоритм существует. И для списков.
Потому что там есть ПОРЯДОК, ЗАДАННЫЙ ПОЛЬЗОВАТЕЛЕМ контейнера.
И именно он реверсируется алгоритмом.
А в мапе НЕТ порядка, заданного пользователем. А то, что что-то там итерируется
и может хранится в каком-то порядке -- не более чем побочный эффект реализации.
Posted via RSDN NNTP Server 2.1 beta
Re[9]: Разместить в обратном порядке отображаемые значения s
> А на самом деле тут исходная позиция не в том, чтобы тащить все функции, которые > возникают на практике, в иинтерфейс, а в том, что прерывается логическая > последовательность использования стандартного алгоритма revrese. То есть он
Тут исходная позиция в том, что ты подразумеваешь какую-то общность всех
контейнеров, которой на самом деле НЕТ. Есть только её видимость, кажущаяся.
Posted via RSDN NNTP Server 2.1 beta
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, MasterZiv, Вы писали:
MZ>On 01/11/2012 05:03 PM, Сыроежка wrote: >> койтесь, как я уже сказал, мир реальных задач значительно богаче вашей фантазии, >> что вам даже и не снилось, какие задачи могут встретиться на практике. Я вам уже >> сказал, что ваш аргумент не состоятелен, так как согласно ему, вообще непонятно, >> зачем существует этот алгоритм, например, для векторов?
MZ>Для векторов как раз всё понятно, зачем этот алгоритм существует. И для списков. MZ>Потому что там есть ПОРЯДОК, ЗАДАННЫЙ ПОЛЬЗОВАТЕЛЕМ контейнера. MZ>И именно он реверсируется алгоритмом.
MZ>А в мапе НЕТ порядка, заданного пользователем. А то, что что-то там итерируется MZ>и может хранится в каком-то порядке -- не более чем побочный эффект реализации.
Я бы не сказал, что в векторе есть порядок, который реверсируется. Реверсируются только значения, хранящиеся в элементах контейнера, а сам порядок остается прежним. Я уже подвел некоторый итог э той теме по адресу http://clipper.borda.ru/?1-6-0-00000022-000-0-0-1326309482
Там я более подробно изложил вопрос. Я не вижу никаких коонтраргументов, препятствующих ввнедрению данного алгоритма для std::map.
Я не считаю это недочетом, но если вы считаете, то можете открыть тему по этому вопросу. С моей точки зрения std::map дополняет понятие вектора, когда к элементам можно обращаться не только по одному виду ключа — беззнаковому целочисленному, но и по произвольному ключу.
>> А на самом деле тут исходная позиция не в том, чтобы тащить все функции, которые >> возникают на практике, в иинтерфейс, а в том, что прерывается логическая >> последовательность использования стандартного алгоритма revrese. То есть он
MZ>Тут исходная позиция в том, что ты подразумеваешь какую-то общность всех MZ>контейнеров, которой на самом деле НЕТ. Есть только её видимость, кажущаяся.
С этим я кардинально не согласен. Есть общность интерфейсов. Именно к этой цели стреились разработчики стандарта. В противном случае нельзя бы было использовать стандартные алгоритмы.
Другое дело, что для вашей точки зрения есть основа, заключающаяся в том, что право на существование конкретного контейнера дает его отличие от других контейнеров. Иначе не стоило бы городить огород и создавать новый шаблонный класс. Но тем не менее это не противоречит общности элементов контейнеров. Эту общность можно уследить, например, на адаптерах контейнеров, как, например, std:;stack,которые в свою основу могут выбрать произвольный контейнер.
> Я не считаю это недочетом, но если вы считаете, то можете открыть тему по этому > вопросу. С моей точки зрения *std::map* дополняет понятие вектора, когда к > элементам можно обращаться не только по одному виду ключа — беззнаковому > целочисленному, но и по произвольному ключу.
Я не знаю, что там с твоей точки зрения, но с точки зрения стандарта в
std::vector пользователь хранит данные в СВОЁМ порядке, в том, какой он
хочет иметь, а в std::map -- в навязанном ему реализацией этого контейнера.
А так -- да, они ПОЛНОСТЬЮ друг друга дополняют. Например, как ворон и
писменный стол. У одного две ноги, у другого (обычно) -- четыре.
Ты прослеживаешь аналогию? Представляешь, У НИХ ОБОИХ ЕСТЬ НОГИ !!
Так что это почти одно и то же !
Вообще, я сходу знаю 4 возможные реализации ассоциативных массивов,
почему STL решили прибить гвоздями к забору под названием "стандарт"
свойства ровно одной из них -- я не понимаю. И считаю это недочётом.
И я не буду открывать тему по этому вопросу. Потому что мне лично на это
наплевать. Есть библиотека, есть везде, извесно, как работает, -- всё.
Более меня не интересует ничего. STL вообще плохая библиотека, её проблемы
меня не интересуют, их там дофига.
Posted via RSDN NNTP Server 2.1 beta
Re[12]: Разместить в обратном порядке отображаемые значения
>> Я не считаю это недочетом, но если вы считаете, то можете открыть тему по этому >> вопросу. С моей точки зрения *std::map* дополняет понятие вектора, когда к >> элементам можно обращаться не только по одному виду ключа — беззнаковому >> целочисленному, но и по произвольному ключу.
MZ>Я не знаю, что там с твоей точки зрения, но с точки зрения стандарта в MZ>std::vector пользователь хранит данные в СВОЁМ порядке, в том, какой он MZ>хочет иметь, а в std::map -- в навязанном ему реализацией этого контейнера. MZ>А так -- да, они ПОЛНОСТЬЮ друг друга дополняют. Например, как ворон и MZ>писменный стол. У одного две ноги, у другого (обычно) -- четыре. MZ>Ты прослеживаешь аналогию? Представляешь, У НИХ ОБОИХ ЕСТЬ НОГИ !! MZ>Так что это почти одно и то же !
MZ>Вообще, я сходу знаю 4 возможные реализации ассоциативных массивов, MZ>почему STL решили прибить гвоздями к забору под названием "стандарт" MZ>свойства ровно одной из них -- я не понимаю. И считаю это недочётом. MZ>И я не буду открывать тему по этому вопросу. Потому что мне лично на это MZ>наплевать. Есть библиотека, есть везде, извесно, как работает, -- всё. MZ>Более меня не интересует ничего. STL вообще плохая библиотека, её проблемы MZ>меня не интересуют, их там дофига.
На мой взгляд и векторе и в отображении пользователь сам выбирает тот порядок, в котором он хочет расположить элементы. Отображение просто пердоставляет пользователю дополнительные возможности по установлению порядка. Ведь как определяется порядок в этих контейнерах? Он определяется прямым доступом к элементам. В веторе этот доступ осуществляется с помощью беззнакового целочисленного ключа, например, c[0[ = 'A'; c[1] = 'B';. То же самое можно сделать и в отображении, если его определить как std::map<unsigned int, char> c;. И работать с ним таким же образом, как и с вектором, c[0[ = 'A'; c[1] = 'B';. С точки зрения интерфейса разницы нет. Но отображение позволяет вводить ключи других типов. Но это всегда тот порядок, который устанавливает сам пользователь.
Здравствуйте, jazzer, Вы писали:
С>>Не просветите меня, с каких это пор список не поддерживает свою организацию хранения данных?! Как раз каждый контейнерсуществует самостоятельно именно из-за того, что поддерживает собственную организацию хранения данных. J>Перечитай мое сообщение еще раз, там речь шла о поддержании отсортирвоанности, а не об организации хранения.
Камрад, ну тут же типичнейший тролль!
Ему уже десять раз разжевали, а он всё кушать хочет.
С>>Что касается всего остального, то это говорит, что вы не в состоянии мыслить концептуально. Вы относитеьс к тем людям, которые не в состоянии обощать, а постоянно решаете частные вопросы. Для программиста — это серьезный недостаток. Я вам советую исправлять его! J>Вы относитесь к людям, которые не в состоянии прочитать внимательно то, что написано. Для программиста — это серьезный недостаток.
Зато для тролля похоже самое оно.
J>А если серьезно, в чем смысл всей этой эскапады? Реклама ресурса клиппер-борда-ру? Или что?
Этож очевидно: ЕДА!
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[7]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Спасибо за развлечение. но когда у меня будет желание посмотреть на кривляние обезьянки, я лучше схожу в зоопарк!
Полагаю такими темпами тебе выпишут абонемент в баню.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[14]: Разместить в обратном порядке отображаемые значения
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>А ключ и значение как раз и являются независимыми.
R>Привожу еще раз цитату из wikipediaна этот раз в более развернутом виде. R>Внимание, читать медленно, вдумчиво, и если что-то не понятно, начать читать заново!
R>
R>Ассоциативный массив (словарь) — абстрактный тип данных (интерфейс к хранилищу данных), позволяющий хранить пары вида «(ключ, значение)» и поддерживающий операции добавления пары, а также поиска и удаления пары по ключу
R>Т.е. std::map хранит в себе пары и позволяет находить и удалять среди них те, которые удовлетворяют условию равенства ключа внутри опять таки этих пар. Постарайтесь представить, что пара это единое целое, внутри которого содержится два поля: ключ и значение. R>И далее пишут следующее:
R>
R>Ассоциативный массив с точки зрения интерфейса удобно рассматривать как обычный массив, в котором в качестве индексов можно использовать не только целые числа, но и значения других типов — например, строки.
R>Т.е. для удобства его представляют как бы массив, но любой вменяемый с++ программист знает, что это не совсем так. R>Так, во всех книжках обращают внимание, что за красивым и удобным интерфейсом вот такого использования:
R>
R>if( m.count(key0) )
R>{
R> m[key0] = value0;
R>}else{
R> m.insert( make_pair(key0, default_value) ); // т.е. для тяжелых типов не есть хорошо!
R> m[key0] = value0;
R>}
R>
R>Но Вы конечно же это не читали, т.к. в это время уже бежали писать статью про std::map на Вашем любимом форуме.
С>>Но в любом случае спасибо вам за участие. Я уже всю дискуссию подытожил в своем сообщении по адресу http://clipper.borda.ru/?1-6-0-00000022-000-0-0-1326309482 С>>Почитайте, будет вам интересно. Я не думаю, что что-то принципиально новое вы сможете мне возразить. То есть я не вижу никаких серьезных контраргументов моей постановке вопроса.
R>Ничего интересного Вы там не пишите. Мне искренне жаль тех, кто решит познать с++ по Вашим статьям.
R>Кстати, "A map satisfies all of the requirements of a container, of a reversible container" означает, что у std::map имеется reverse_iterator, const_reverse_iterator, rbegin(), rend(). И совсем не обязан иметь средство реверсивного расположения значений элементов! Вы бы хотя бы стандарт открыли что-ли!? И вообще курите поменьше ту дрянь, что дает Вам возможность думать настолько обобщенно и концептуально..
R>P.S. Когда в следующий раз захотите выпендриться на своем форуме за счет Саттера, хотя бы прочитайте ВНИМАТЕЛЬНО то, что он пишет, например комменты к коду. Если не поняли с первого раза, читайте пока не дойдет, а уже потом пишите статьи, про то, какой Вы умный!
Дело в том, что когда вы цитируете описание std::map, вы просто перечисляете открытый интерфейс этого контейнера, то есть те функции-члены, которые есть в контейнере. Но при этом никак не можете понять, что ключ и отображаемое значение — это независимые между собой части. В том смысле, что один раз завяде элемент контейнера, вы затем отображаемое значение этого элемента можете менять сколько угодно раз. Но хуже того, вы даже сами не понимаете то, что цитируете. Вы цитируете сходство с вектором, не понимая того, что имеется виду общий способ обращения по ключу к элементу, только у вектора этот ключ имеет заранее определенный тип unsigned int, и сами ключи должны следовать без пропусков. Что это означает? Это означает, что лишь организован доступ по ключу, но пользователь работает с отображаемыми объектами! Ключ играет роль индекса к элементу, а изменяется именно отображаемое значение. Работает пользовательна самом деле не с парой, так как первый элемент пары — это константное значение, а именно с отображаемым значением. Ключи создаются только раз и больше никакой роли кроме роли индекса к элементу не играют. Далее пользователь работает с отображаемым значением, модифицируя его по мере необходимости и пока элемент не будет удален. То есть изменение элемента относится именно к отображаемому значению, а не ключу. Поэтому реверсировать отображаемые значения для std::map это также естественно, как и для вектора, так как реверсия — это ничто иное, как изменение хранимых значений, а контейнеры для того и существуют, чтобы можно было менять значения.
Что касается Герба Саттера, то, извините, ничего конкретного вы не сказали. Так что это всего лишь ваше словоблудие. Если есть что сказать по существу, то говорите. Если я там что-то неправильно написал, то там и укажите, что я неправильно написал. Иначе вы выглядите, как бы сказать, ментором, который сам себе присвоил этот титул. То есть совершенно необосновано.
А то, что, якобы, я не интересно написал про reverse для std::map говорит лишь об одном, что вы не понимаете проблему. А стандарт как раз и движется в том направлении, которое я указал. Поэтому есть два варианта: либо расширить формы алгоритма std::reverse, либо добавить функцию-член класса в std::map. Я уже написал расширенную форму алгоритма std::reverse, которая позволяет работать с любым контейнером. Это наиболее гибкий подход, который не требует расширения существующего интерфейса std::map, Но чтобы это сдделать, нужно вникнуть и понимать проблему. Вы ее к сожалению не понимаете, так как цитируете банальный материал, без осознания сущности контейнеров, что контейнеры предназначены для изменения хранимых в них данных. А потмоу способы изменения данных долны быть унифицированы и просты в использовании. А этого для std::mmap в настоящее время нет. Поэтому это и является явным упущением стандарта.
R>if( m.count(key0) )
R>{
R> m[key0] = value0;
R>}else{
R> m.insert( make_pair(key0, default_value) ); // т.е. для тяжелых типов не есть хорошо!
R> m[key0] = value0;
R>}
R>
Вот вы написали банальную вещь. Допустим вы создали элемент std::map, а дальше-то что?! Можете вы этому элементу присвоить новое отображаемое значение или нет? То есть создали вы элемент с помощью m[key1] = value1;, а дальше разве это так и остается неизменным? Нет, конечно. Далее вы будете менять значения ваших элементов, то есть будут чаксто встречаться операторы m[key1] = value2; m[key1] = value3; m[key1] = value 4; и т.д. А что такое операция инверсии? Это тоже самое изменение значений элементов. Как вы ее собираетесь выполнять? И почему вы считаете, если изменять значения элементов можно, но нельзя деать операцию reverse? Чем она отличается от простого изменения элемента контейнера std::map?!Да ничем! Просто исходное новое значение вы берете из другого элемента этого же контейнера. Только и всего. Но теперь возникает вопрос, а как сделать эту операцию эффективно и корректно? Очевидно, что семантически действие этой операции одинаково для всех контейнеров, точно также, как операция swap семантически одинакова для всех контейнеров и объектов, независимо от их организации. Главное требование — это всего лишь, чтобы контейнер был реверсивным, то есть чтобы он имел двусторонний итератор или итератор произвольного доступа. Это является достаточным условием в общем случае для применения операции реверсии. И чего вы никак понять не можете. А если все условия выполняются и потребность в такой операции есть, то возникает второй вопрос? почему эта операция отсутствует для заданного контейнера? Оказывается, что на самом деле никаких оснований, чтобы эта операция у std::map отсутствовала, нет! Вот чего вы не понимаете.
Я вам настоятельно рекомендую почитать книгу Скотта Майерса "Эффективное использование STL" в частнсти его совет 23 "Используйте возможность замены ассоциативных контейнеров сортированными векторами", и тогда вы поймете, что между веторами и ассоциативными контейнерами существует неформальная связь.
То есть прежде чем цитировать мне банальные вещи, вы постарайтесь понять суть этих контейнеров и неформальную связь между ними, и тогда вы поймете смысл поставленной мною проблемы.
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, rumit7,
С>Я вам настоятельно рекомендую почитать книгу Скотта Майерса "Эффективное использование STL" в частнсти его совет 23 "Используйте возможность замены ассоциативных контейнеров сортированными векторами", и тогда вы поймете, что между веторами и ассоциативными контейнерами существует неформальная связь. С>То есть прежде чем цитировать мне банальные вещи, вы постарайтесь понять суть этих контейнеров и неформальную связь между ними, и тогда вы поймете смысл поставленной мною проблемы.
Спорить с Вами безполезное занятие, т.к. любой аргумент, будь то высказывание Майерса, Саттера или цитата из стандарта Ваш больной мозг трактует как подтверждение Вашей гениальности!
За сим спрошу прямо — что за травку курим?
Re[4]: Разместить в обратном порядке отображаемые значения s
>> MZ>Порядок хранения элементов в std::map не определён. Обратным порядком для >> MZ>неоределённого порядка будет также неопределённый порядок. Следовательно, >> MZ>тебе ПРОСТО НЕ НУЖНО НИЧЕГО ДЕЛАТЬ. >> >> Ты что-то путаешь. Порядок на множестве ключей определен и этот порядок для
MZ>Определён порядок на ключах. И порядок итерирования. Порядок хранения -- не MZ>определён.
А с какой стороны нам поможет знание устройства хранения? Прикладные задачи едва ли полагаются на это. Они оперируют публичным контрактом класса перед клиентом: интерфейсом и гарантиями сложности методов. В данному случае с std::map публичный контракт определен стандартом и с какой стороны меня должно трогать его внутреннее устройство с прикладной точки зрения?
Re[17]: Разместить в обратном порядке отображаемые значения
Здравствуйте, Сыроежка, Вы писали:
С>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap.
For each non-negative integer i <= (last — first)/2, applies iter_swap to all pairs of iterators first + i, (last — i) — 1.
C++ Standart 2003, 25.2.2 Swap:
template<class T> void swap(T& a, T& b);
Requires: Type T is CopyConstructible (20.1.3) and Assignable (23.1).
C++ Standart 2003, 23.1 Container requirements, Table 64—Assignable requirements:
expression | return type | post-condition
-------------------------------------------------
t = u | T& | t is equalent to u
-------------------------------------------------
In the map class template, these are bidirectional iterators.
Dereferencing this iterator accesses the element's value, which is of type pair<const Key,T>.
Следовательно, pair<const Key,T> не может использовать swap. На мой взгляд, стандарт последователен в данном случае.
С>Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает. То есть я вообще мог здесь не распинатьсяы, а указать просто на то, что стандарт не выполняет своих обязательств. То есть он был по крайней мере в разделе стандартных алгоритмов для этого алгоритма указать все исключения его применения, если основные требования выполнены, такие, как, например, наличие двустороннего итератора. Но этого нет. Этого вполне достатончо, чтобы заявить, что стнадарт содержит серьезные упущения.
Re[18]: Разместить в обратном порядке отображаемые значения
Здравствуйте, Centaur, Вы писали:
C>Здравствуйте, Сыроежка, Вы писали:
С>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего,
C>Выполняется.
С>>а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap.
C>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
C>То, чего вы хотите — это итератор по значениям std::map. К паре таких итераторов будет применим стандартный алгоритм std::reverse. И они уже реализованы в библиотеке boost::range.
C>И тем не менее, это не отменяет того, что перестановка значений при сохранении ключей осмысленна только в узком частном случае, когда ключи образуют непрерывный отрезок натурального ряда.
Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap?
Во-вторых, совершенно не понятно, почему имеет смысл только для частного сулчая, когда ключи образуют непрерывный отрезок натурального ряда? А если в качества ключей идут строки, причем не непрерывно согласно их кодам, то что тогда?!
Здравствуйте, Сыроежка, Вы писали:
С>Дело в том, что когда вы цитируете описание std::map, вы просто перечисляете открытый интерфейс этого контейнера, то есть те функции-члены, которые есть в контейнере. Но при этом никак не можете понять, что ключ и отображаемое значение — это независимые между собой части. В том смысле, что один раз завяде элемент контейнера, вы затем отображаемое значение этого элемента можете менять сколько угодно раз. Но хуже того, вы даже сами не понимаете то, что цитируете. Вы цитируете сходство с вектором, не понимая того, что имеется виду общий способ обращения по ключу к элементу, только у вектора этот ключ имеет заранее определенный тип unsigned int, и сами ключи должны следовать без пропусков. Что это означает? Это означает, что лишь организован доступ по ключу, но пользователь работает с отображаемыми объектами! Ключ играет роль индекса к элементу, а изменяется именно отображаемое значение. Работает пользовательна самом деле не с парой, так как первый элемент пары — это константное значение, а именно с отображаемым значением. Ключи создаются только раз и больше никакой роли кроме роли индекса к элементу не играют. Далее пользователь работает с отображаемым значением, модифицируя его по мере необходимости и пока элемент не будет удален. То есть изменение элемента относится именно к отображаемому значению, а не ключу. Поэтому реверсировать отображаемые значения для std::map это также естественно, как и для вектора, так как реверсия — это ничто иное, как изменение хранимых значений, а контейнеры для того и существуют, чтобы можно было менять значения.
std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
Re[18]: Разместить в обратном порядке отображаемые значения
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap.
R>C++ Standart 2003, 25.2.9 Reverse:
R>
R>For each non-negative integer i <= (last — first)/2, applies iter_swap to all pairs of iterators first + i, (last — i) — 1.
R>C++ Standart 2003, 25.2.2 Swap:
R>
R>template<class T> void swap(T& a, T& b);
R>Requires: Type T is CopyConstructible (20.1.3) and Assignable (23.1).
R>C++ Standart 2003, 23.1 Container requirements, Table 64—Assignable requirements:
R>
R>expression | return type | post-condition
R>-------------------------------------------------
R>t = u | T& | t is equalent to u
R>-------------------------------------------------
R>In the map class template, these are bidirectional iterators.
R>Dereferencing this iterator accesses the element's value, which is of type pair<const Key,T>.
R>Следовательно, pair<const Key,T> не может использовать swap. На мой взгляд, стандарт последователен в данном случае.
С>>Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает. То есть я вообще мог здесь не распинатьсяы, а указать просто на то, что стандарт не выполняет своих обязательств. То есть он был по крайней мере в разделе стандартных алгоритмов для этого алгоритма указать все исключения его применения, если основные требования выполнены, такие, как, например, наличие двустороннего итератора. Но этого нет. Этого вполне достатончо, чтобы заявить, что стнадарт содержит серьезные упущения.
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Сыроежка, Вы писали:
С>>Дело в том, что когда вы цитируете описание std::map, вы просто перечисляете открытый интерфейс этого контейнера, то есть те функции-члены, которые есть в контейнере. Но при этом никак не можете понять, что ключ и отображаемое значение — это независимые между собой части. В том смысле, что один раз завяде элемент контейнера, вы затем отображаемое значение этого элемента можете менять сколько угодно раз. Но хуже того, вы даже сами не понимаете то, что цитируете. Вы цитируете сходство с вектором, не понимая того, что имеется виду общий способ обращения по ключу к элементу, только у вектора этот ключ имеет заранее определенный тип unsigned int, и сами ключи должны следовать без пропусков. Что это означает? Это означает, что лишь организован доступ по ключу, но пользователь работает с отображаемыми объектами! Ключ играет роль индекса к элементу, а изменяется именно отображаемое значение. Работает пользовательна самом деле не с парой, так как первый элемент пары — это константное значение, а именно с отображаемым значением. Ключи создаются только раз и больше никакой роли кроме роли индекса к элементу не играют. Далее пользователь работает с отображаемым значением, модифицируя его по мере необходимости и пока элемент не будет удален. То есть изменение элемента относится именно к отображаемому значению, а не ключу. Поэтому реверсировать отображаемые значения для std::map это также естественно, как и для вектора, так как реверсия — это ничто иное, как изменение хранимых значений, а контейнеры для того и существуют, чтобы можно было менять значения.
I>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
Так сложности нет и в том, чтобы написать все стандартные алгоритмы! Только зачем каждый раз это делать, вы можете объяснить? Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size().
Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Почему это к std::pair нельзя применить swap?
R>У меня было написано, что к std::pair<const Key,T> нельзя применить swap.
R>Вот здесь
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
C>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. Эта форма алгоритма напрашивается не только для std::map, а может быть применима для любого типа контейнера, когда мы ходим менять не целиком элементы, а их части. То есть имеется, например, достаточно гибкая форма алгоритма std::transform, алгоритм std:;reverse тоже заслуживает того, чтобы приобрести большую гибкость. Как я указывал, приведенный в начале дискуссии пример самодельного такого алгоритма совершенно не удовлетворителен. Он даже не работает, если нужно реверсировать не весь контейнер, а всего лишь его диапазон. А наличие формы контейнера std::reverse.которую я привел, решала бы все проблемы.
Вот как, например, выглядел бы тогда соответсвующий код
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
C>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. Эта форма алгоритма напрашивается не только для std::map, а может быть применима для любого типа контейнера, когда мы ходим менять не целиком элементы, а их части. То есть имеется, например, достаточно гибкая форма алгоритма std::transform, алгоритм std:;reverse тоже заслуживает того, чтобы приобрести большую гибкость. Как я указывал, приведенный в начале дискуссии пример самодельного такого алгоритма совершенно не удовлетворителен. Он даже не работает, если нужно реверсировать не весь контейнер, а всего лишь его диапазон. А наличие формы контейнера std::reverse.которую я привел, решала бы все проблемы.
С>Вот как, например, выглядел бы тогда соответсвующий код
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, rumit7, Вы писали:
R>>Здравствуйте, Сыроежка, Вы писали:
С>>>Почему это к std::pair нельзя применить swap?
R>>У меня было написано, что к std::pair<const Key,T> нельзя применить swap.
R>>Вот здесь
Вам ответили почему.
R>А там наверху я для кого приводил цитату из стандарта? Прочитайте требования для swap.
Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным. То есть фя уже приводил аналогию с вектором, у которого ключ, то есть индекс элементов является константным, но переставляем мы же не индексы элементов, а хранимые значения. То же самое и с отображением. первый элемент пары служит ключом, то есть индексом хранимого значения. Мы его так и используем для индексации элементов, но меняем же мы хранимые значения. И я самого начала предлагал реверсировать хранимые значения. Именно поэтому я и предлагаю новую форму алгоритма std:;reverse с предикатом, с помощью которого можно извлечь из итератора хранимое значение и его обменять с другим таким же значением.
Здравствуйте, Masterkent, Вы писали:
M>IMHO, в стандартной библиотеки есть куда более неприятные пробелы — например, отсутствие у файловых потоков конструктора, принимающего имя файла в юникоде (что для меня во многих случаях делает такие потоки бесполезными).
Я так понимаю, все вопросы к базовой fopen, строчка просто переправляется туда без изменений:
It then opens a file, if possible, whose name is the NTBS s (‘‘as if’’ by calling std::fopen(s,modstr)).
Т.е. если fopen может открыть файл с юникодным именем (на которое имеется голый указатель сhar*), то и fstream сможет.
Сам не проверял, если что, мне юникод не нужен
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Сыроежка, Вы писали:
I>>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>>Так сложности нет и в том, чтобы написать все стандартные алгоритмы! I>Раз нет сложности, то напиши и используй.
С>>Только зачем каждый раз это делать, вы можете объяснить? I>Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
I>Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит. I>Даже если вас съели, у вас как минимум два выхода.
Вызнаете разницу между тем, что алгоритм присутствует в стандарте, и во всех проектах используется этот алгоритм, и тем, что в каждом команда разрабатывает свой алгоритм?
В том-то и проблема, что как раз в стандарте не хватает той формы алгоритма, которую я здесь уже привел. Она органически всотребована для многих задач. Даже если рассмотреть аткую простую задачу, как если бы вектор хранилл в качестве элементов некую структуру, и нужно реверсировать не целиком всю структуру, а лишь некоторые ее поля, то уже возникает сложность, так как нет подходящего средства!
Здравствуйте, Сыроежка, Вы писали:
С>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
Так что — нарушает стандарт или нет?
Re[22]: Разместить в обратном порядке отображаемые значения
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>Здравствуйте, Сыроежка, Вы писали:
C>>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. J>Проблему свопа пар с константой решить нельзя в принципе. J>Новая форма алгоритма для мапа также не нужна, на этот счет есть бритва Оккама. J>map предоставляет двунаправленный итератор по парам ключ+значение. J>Используя Boost.Iterator, можно легко превратить этот итератор в двунаправленный же итератор по значениям, после чего можно применять к нему любые стандартные алгоритмы, включая reverse, random_shuffle, permutation и т.д. J>Это — единственный осмысленный путь, а то, что предлагаешь ты — концептуально неправильно.
Я как раз не вижу ничего осмысленного в этом пути. Это как раз путь через одно место. Нужно использовать третьестороннюю библиотеку, которую не всегда разоешается использовать в проектах. Во-вторых, нужны всякие преобразования итераторов, которые затрудняют чтение кода. Так что я с вами не сооглашусь.
Самый простой пути — это тот, который я привел в вииде конерктного кода. Он совершенно ясен для читающегог код и не требует никаких ухищрений. Более того эту форму алгоритма можно использзовать не обязательно с sttd::map, но и в ттех случаях, когда надо реверсировать не полностью элемент такой, как, например, структура, а лишь отдельные ее члены. Тогда у вас снова возникает трудноразрешимая задача, если у вас нет такой формы алгоритма.
Попробуйте решить такую простую задачу, когда у вас есть вектор структур и надо реверсировать только пару полей этой структуры для диапазона элементов вектора. Что делать в этом случае?
Проблема в том, что нет формы алгоритма std::reverse с предикатом. То есть для пользователя этот алгоритм как черный ящик, в процесс работы которого нельзя вмешаться. Предоставление формы этого алгоритма с предикатом очень хорошо вписывается в общую архитектуру стандартных алгоритмов.
Здравствуйте, Сыроежка, Вы писали:
С>Я как раз не вижу ничего осмысленного в этом пути. Это как раз путь через одно место. Нужно использовать третьестороннюю библиотеку, которую не всегда разоешается использовать в проектах. Во-вторых, нужны всякие преобразования итераторов, которые затрудняют чтение кода. Так что я с вами не сооглашусь.
Ничего они не затрудняют в пользовательском коде, посмотри на boost.range.
С>Самый простой пути — это тот, который я привел в вииде конерктного кода. Он совершенно ясен для читающегог код и не требует никаких ухищрений. Более того эту форму алгоритма можно использзовать не обязательно с sttd::map, но и в ттех случаях, когда надо реверсировать не полностью элемент такой, как, например, структура, а лишь отдельные ее члены. Тогда у вас снова возникает трудноразрешимая задача, если у вас нет такой формы алгоритма.
Тебе придется написать такого рода специальные версии всех остальных алгоритмов, которые полагаются на swap (а в С++11 — еще и move).
random_shuffle, например, да и sort туда же.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>
R>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>Так что — нарушает стандарт или нет?
Здесь не все так просто, как кажэется, так как вы можете специализировать функцию swap для элементов вашего контейнера. Так что это на усмотрение пользователя контейнера, предоставляет он такую функцию или нет.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>
R>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>Так что — нарушает стандарт или нет?
Обратите внимание нра эту часть стандарта:
"3 The context in which swap(t, u) and swap(u, t) are evaluated shall ensure that a binary non-member
function named “swap” is selected via overload resolution (13.3) on a candidate set that includes:
— the two swap function templates defined in <utility> (20.2) and
— the lookup set produced by argument-dependent lookup (3.4.2)."
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, Igore, Вы писали:
I>>>Здравствуйте, Сыроежка, Вы писали:
I>>>>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>>>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>>>>Так сложности нет и в том, чтобы написать все стандартные алгоритмы! I>>>Раз нет сложности, то напиши и используй.
С>>>>Только зачем каждый раз это делать, вы можете объяснить? I>>>Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>>>>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>>>>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
I>>>Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит. I>>>Даже если вас съели, у вас как минимум два выхода.
С>>Вызнаете разницу между тем, что алгоритм присутствует в стандарте, и во всех проектах используется этот алгоритм, и тем, что в каждом команда разрабатывает свой алгоритм? I>Повторю еще раз, то что тебе написали, пиши в комитет с просьбой включения в стандарт нового алгоритма. Или создай свою STL с блэкджеком и ну ты понял, разрекламируй ее и может она станет еще одним de facto, как буст, можешь туда попробовать добавить свои идеи
С>>В том-то и проблема, что как раз в стандарте не хватает той формы алгоритма, которую я здесь уже привел. Она органически всотребована для многих задач. Даже если рассмотреть аткую простую задачу, как если бы вектор хранилл в качестве элементов некую структуру, и нужно реверсировать не целиком всю структуру, а лишь некоторые ее поля, то уже возникает сложность, так как нет подходящего средства!
I>Тебе уже несколько раз объясняли, я повторю, map<int, int> = vector<pair<const int, int>>, тогда reverse это просто обход в обратном порядке, так как лезть во внутренее устройства map мы не можем.
С>>реверсировать не целиком всю структуру, а лишь некоторые ее поля I>Это трансформация а не реверсирование.
I>Реверсирование просто и понятно, а тебе хочется немного другого, я бы на твоем месте сменил тип контейнера и не мучился I>
А реверсирование в частности и является трансформацией исходной последовательностиЮ если не используется форма с copy. Так что одного обхода не достатоноч. Что делать, если нужно изменить существующие значения?!
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Я как раз не вижу ничего осмысленного в этом пути. Это как раз путь через одно место. Нужно использовать третьестороннюю библиотеку, которую не всегда разоешается использовать в проектах. Во-вторых, нужны всякие преобразования итераторов, которые затрудняют чтение кода. Так что я с вами не сооглашусь. J>Ничего они не затрудняют в пользовательском коде, посмотри на boost.range.
С>>Самый простой пути — это тот, который я привел в вииде конерктного кода. Он совершенно ясен для читающегог код и не требует никаких ухищрений. Более того эту форму алгоритма можно использзовать не обязательно с sttd::map, но и в ттех случаях, когда надо реверсировать не полностью элемент такой, как, например, структура, а лишь отдельные ее члены. Тогда у вас снова возникает трудноразрешимая задача, если у вас нет такой формы алгоритма.
J>Тебе придется написать такого рода специальные версии всех остальных алгоритмов, которые полагаются на swap (а в С++11 — еще и move). J>random_shuffle, например, да и sort туда же.
Пока что достаточно хотя бы добавить новую форму для reverse. Это уже было бы прогрессом и решало множество задач, которые без наличия такой формы алгоритма решить не просто.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, rumit7, Вы писали:
R>>>Здравствуйте, Сыроежка, Вы писали:
С>>>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>>>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>>>
R>>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>>>Так что — нарушает стандарт или нет?
С>>Здесь не все так просто, как кажэется,
R>Я задал простой вопрос. На простой вопрос можно ответить просто — да или нет.
С>>так как вы можете специализировать функцию swap для элементов вашего контейнера. Так что это на усмотрение пользователя контейнера, предоставляет он такую функцию или нет.
R>Это все отмазки.. Поменьше кидайтесь громкими фразами, реже придется выглядить глупо..
Это не отговорки. Вы в своем пространстве имен заводите функцию swap для вашей специализации класса std:::paiir, и получаете swapable элементы контейнера.
То есть фоормально сттандарт говорит о том, есть ли у него под рукой функция swap, которую он может применить или нет. Это уже на ваше усмотрение, предоставлять компилятору такую функцию или нет.
Здравствуйте, Сыроежка, Вы писали:
J>>Тебе придется написать такого рода специальные версии всех остальных алгоритмов, которые полагаются на swap (а в С++11 — еще и move). J>>random_shuffle, например, да и sort туда же.
С>Пока что достаточно хотя бы добавить новую форму для reverse. Это уже было бы прогрессом и решало множество задач, которые без наличия такой формы алгоритма решить не просто.
Абсолютно недостаточно. Как только ты включишь эту версию reverse в стандарт, тут же появится Сыроежка2, который объявит отсутствие аналогичных версий всех остальных обменивающих алгоритмов "существенным упущением стандарта". Так что либо все, либо ничего.
Это аналогично тому, предоставляете ли вы конструктор копирования, или не предоставляете его для класса, делая закрытым. если предоставляете, то у вас элемент удовлетворять требованию копируемости. А не предоставите, то не будет удовлетворять этому требованиб. Но все это на ваше усмотрение.
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, Centaur, Вы писали:
C>>Здравствуйте, Сыроежка, Вы писали:
С>>>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения. С>>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
C>>Потому что эта операция в общем случае неосмысленна.
С>Не говорите "гоп" пока не перепрыгнули! Это для вас она сейчас является неосмысленной, потому что вы не в состоянии сейчас что-то придумать. А практика показывает, что существующие задачи настолько разнообразны, что не хватит никакой фантазии человека, чтобы представить все задачи, с которыми стаокивается программист!
И это всё должны были учитывать авторы архитектуры стандартных контейнеров N лет назад?
Вы не находите противоречия в своих запросах?
PS А потом понадобится менять жлемены через 1 и снова.
Re[8]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, blackhearted, Вы писали:
B>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, Centaur, Вы писали:
C>>>Здравствуйте, Сыроежка, Вы писали:
С>>>>Задача простая: для заданного контейнера std::map реверсировать отображаемые значения. С>>>>Хочу понять, почему такой алгоритм не включен в качестве функции-члена класса std::map.
C>>>Потому что эта операция в общем случае неосмысленна.
С>>Не говорите "гоп" пока не перепрыгнули! Это для вас она сейчас является неосмысленной, потому что вы не в состоянии сейчас что-то придумать. А практика показывает, что существующие задачи настолько разнообразны, что не хватит никакой фантазии человека, чтобы представить все задачи, с которыми стаокивается программист!
B>И это всё должны были учитывать авторы архитектуры стандартных контейнеров N лет назад? B>Вы не находите противоречия в своих запросах?
B>PS А потом понадобится менять жлемены через 1 и снова.
Нет, у меня таких претензий нет. Как раз напротив, я вижу, что стандарт развивается в том направдлении, которое я себе представляю. например, я уже отметил положительные стороны развития адаптеров контейнеров. Вы моожете ознакомиться с моей точкой зрения по ссылке
Здравствуйте, Сыроежка, Вы писали:
С>Я вам больше скажу, у мен только версий алгоритма for_each около 20, если мне память не изменяет. И я не виижу причин не включить их в стандарт. напротив, в своей рпактике я всегда сталкивался с ненужными ограничениями и изобретением велосипеда.
20? В студию такое чудо!
С>Сами подумайте, например, насколько бы был полезен алгоритм for_each_if
Ни насколько. Есть Boost.Range, который все это делает в нормальном читабельном виде.
А твой for_each_if(a.begin(),a.end(),f,g) — кто из f и g фильтр, а кто — актор?
А в Boost.Range это будет for_each( a|filtered(f)|sorted(h)|reversed, g)
С>ксати сказать, вы забыли, что в стандарт включены такие примитивные алгоримты, как all_of и any_of. Так что помимо Сыроежек хватает и других программистов!
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Я вам больше скажу, у мен только версий алгоритма for_each около 20, если мне память не изменяет. И я не виижу причин не включить их в стандарт. напротив, в своей рпактике я всегда сталкивался с ненужными ограничениями и изобретением велосипеда. J>20? В студию такое чудо!
С>>Сами подумайте, например, насколько бы был полезен алгоритм for_each_if J>Ни насколько. Есть Boost.Range, который все это делает в нормальном читабельном виде. J>А твой for_each_if(a.begin(),a.end(),f,g) — кто из f и g фильтр, а кто — актор? J>А в Boost.Range это будет for_each( a|filtered(f)|sorted(h)|reversed, g)
С>>ксати сказать, вы забыли, что в стандарт включены такие примитивные алгоримты, как all_of и any_of. Так что помимо Сыроежек хватает и других программистов!
J>Как это относится к тезису "все или ничего"?
Ну так вы, значит, сами себя обманываете! Вы говорите, что не надо расширять STL, в то время как сами активно пользуетесь его расширенями, заложенными в boost.
Я ратую за то, чтобы STL был самодостаточным.
Здравствуйте, Сыроежка, Вы писали: С>Ну так вы, значит, сами себя обманываете! Вы говорите, что не надо расширять STL, в то время как сами активно пользуетесь его расширенями, заложенными в boost. С>Я ратую за то, чтобы STL был самодостаточным.
Еше раз скажу, попробуй внимательно читай то, что тебе пишут
Здравствуйте, Сыроежка, Вы писали:
С>>>реверсировать не целиком всю структуру, а лишь некоторые ее поля I>>Это трансформация а не реверсирование.
I>>Реверсирование просто и понятно, а тебе хочется немного другого, я бы на твоем месте сменил тип контейнера и не мучился I>>
С>А реверсирование в частности и является трансформацией исходной последовательностиЮ если не используется форма с copy. Так что одного обхода не достатоноч. Что делать, если нужно изменить существующие значения?!
Все, STL головного мозга
Транформация изменяет элементы, реверсирование изменяет порядок элементов. Для тебя это одинаковые вещи, для меня нет.
Тебе не достаточно аргументов которые тебе привели, ты остался на своем мнение, на эту тему больше писать не буду.
Если ты не знаешь что нужно делать для изменения значений в контейнере, то меняй профессию. Решений твоей проблемы было приведено достаточно, в том числе тобой, переливать из пустого в порожнее мне надоело. Задачи надо решать, а не рассуждать, как бороздят корабли просторы большого театра. STL это просто инструмент, микроскопом можно заколачить гвозди, но он для другого предназначен.
Это код для размышления, можно не отвечать на сообщение, общение закончено.
typedef std::map<int, int> intmap;
intmap m;
m[0] = 0;
m[1] = 1;
m[2] = 2;
std::vector<intmap::value_type> vec;
std::transform(m.begin(), m.end(), m.rbegin(), std::back_inserter(vec), [](intmap::value_type a, intmap::value_type b)
{
return std::make_pair(a.first, b.second);
});
Re[5]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, Сыроежка, Вы писали:
С>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
std::map хранит пары значений ключей, как элемент. Но можно выкрутиться использовав "iterator adaptor" который ходит по мутабельным значениям и применить стандартный reverse.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[18]: Разместить в обратном порядке отображаемые значения
On 01/12/2012 10:27 AM, Centaur wrote:
> И тем не менее, это не отменяет того, что перестановка значений при сохранении > ключей осмысленна только в узком частном случае, когда ключи образуют > непрерывный отрезок натурального ряда.
Да она просто на фиг никому не нужна, потому как ключ -- это часть значения
обычно. Чтоб ключ записи не лежал в записи -- это надо что-то такое придумать ...
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Разместить в обратном порядке отображаемые значения s
Здравствуйте, minorlogic, Вы писали:
M>Здравствуйте, Сыроежка, Вы писали:
С>>Как проще выполнить реверсию значений элементов для заданного контейнера std::map? То есть ключи остаются на месте, а меняются в обратном порядке отображаемые значения.
M>std::map хранит пары значений ключей, как элемент. Но можно выкрутиться использовав "iterator adaptor" который ходит по мутабельным значениям и применить стандартный reverse.
Проблема в том, что в стандарте нет такого адаптера итератора. Поэтому лучше ввести форму этого алгоритма с предикатом. Тогда не только можно использовать с контейнером sttd::map, но и решать задачи, когда для последовательного контейнера нужно реверсировать не весь элемент целиком, а, допустим, его подчлены. То есть, например, если у вас элементом является некоторая структуру, то нужно реверсировать не всю структуру, а лишь отдельные ее члены.
Сейчас эту задачу даже для последовательного контейнера нельзя решить с помощью стандартного аллгоритма, так как у пользователя нет возможности управлять его работой. Ежели появится форма этого алгоритма с предикатом, то пользователь в предикате может задавать требуемые операции.
Здравствуйте, Сыроежка, Вы писали:
С>Проблема в том, что в стандарте нет такого адаптера итератора.
Я не утверждал что есть, я лишь предложил STL way решение.
С> Поэтому лучше ввести форму этого алгоритма с предикатом. Тогда не только можно использовать с контейнером sttd::map, но и решать задачи, когда для последовательного контейнера нужно реверсировать не весь элемент целиком, а, допустим, его подчлены. То есть, например, если у вас элементом является некоторая структуру, то нужно реверсировать не всю структуру, а лишь отдельные ее члены.
Не лучше. Универсальнее использовать адапторы итераторов которые могут ссылаться на class members.
С>Сейчас эту задачу даже для последовательного контейнера нельзя решить с помощью стандартного аллгоритма, так как у пользователя нет возможности управлять его работой. Ежели появится форма этого алгоритма с предикатом, то пользователь в предикате может задавать требуемые операции.
Порассуждайте не над возможностью , а над целесообразностью.
... << RSDN@Home 1.2.0 alpha 5 rev. 1539>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[6]: Разместить в обратном порядке отображаемые значения s