Re[7]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 16:05
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Но если уж и апеллировать к авторитетам, то в области алгоритмов C++ нужно ровняться на Степанова — он спокойно использует беззнаковые, и ЕМНИП даже рекомендовал в одной из лекций
Автор: andyp
Дата: 17.07.13
.


Ну вот некоторое время назад был холивар как раз по поводу STL, и как она ужасна, и что "написал он ее в больнице, и не иначе, как то была больница Степанова-Скворцова ит.п.". Тут можно до бесконечности кидаться ссылками, конечно...

И меряться авторитетами основоположников тоже можно долго


EP>Использование знаковых целых, там где по смыслу подходят беззаконные (да ещё и имеют большую "ёмкость") — это что-то из области babysitting'а, причём не особо удачного. Если уж нужна нянька — то тогда уже брать safe int и им подобные.


Одна беда: если ты пишешь под фреймворк, где используются знаковые, то у тебя особого выбора нет. В чужой монастырь со своим уставом (даже не со своим, а со степановским)... Я бы вот предпочел использовать везде size_t, вроде для того оно и предназначалось, но, увы...
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Отредактировано 15.10.2014 16:06 slava_phirsov . Предыдущая версия .
Re[8]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 16:14
Оценка: :)
Здравствуйте, slava_phirsov, Вы писали:

EP>>Но если уж и апеллировать к авторитетам, то в области алгоритмов C++ нужно ровняться на Степанова — он спокойно использует беззнаковые, и ЕМНИП даже рекомендовал в одной из лекций
Автор: andyp
Дата: 17.07.13
.

_>Ну вот некоторое время назад был холивар как раз по поводу STL, и как она ужасна, и что "написал он ее в больнице, и не иначе, как то была больница Степанова-Скворцова ит.п.".

STL одна из лучших библиотек которые я видел, я бы сказал даже лучшая
Что конкретно "ужасного" там?
Re[9]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 16:26
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>STL одна из лучших библиотек которые я видел, я бы сказал даже лучшая

EP>Что конкретно "ужасного" там?

Не буду цитировать холиварщиков, тем более, что я не разделяю многие из их аргументов, гугл в помощь, если интересно. Вроде читал даже на КЫВТе сенсационный пост типа "Александреску опускает итераторы"
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[10]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 16:36
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

EP>>STL одна из лучших библиотек которые я видел, я бы сказал даже лучшая

EP>>Что конкретно "ужасного" там?
_>Не буду цитировать холиварщиков, тем более, что я не разделяю многие из их аргументов, гугл в помощь, если интересно. Вроде читал даже на КЫВТе сенсационный пост типа "Александреску опускает итераторы"

То решение которое он предлагает в D крайне спорное. Точнее оно отлично подходит для InpuntRange, а вот начиная с ForwardRange начинаются серьёзные проблемы. Всё подробно описано в этом топике
Автор: matumba
Дата: 21.10.13
.

И, кстати, на эту тему недавно был доклад — там также отмечается, что хоть в некоторых крайне специфичных случаях D Range это удобно, но в общем случае менее мощное средство чем итераторы.
Re[11]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 16:42
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>То решение которое он предлагает в D крайне спорное. Точнее оно отлично подходит для InpuntRange, а вот начиная с ForwardRange начинаются серьёзные проблемы. Всё подробно описано в этом топике
Автор: matumba
Дата: 21.10.13
.


Что до меня, то только то, что, в STL, к примеру, для копирования требуется не забыть переразмерить контейнер-приемник (вариант — не забыть использовать std::inserter), что std::remove на самом деле не удаляет, а просто перетасовывает элементы, и то, что большинство библиотечных алгоритмов принимают кучку однотипных аргументов (подходя формально — "bad smell" в чистом виде) — это все не есть достоинства.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[12]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 17:14
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>Что до меня, то только то, что, в STL, к примеру, для копирования требуется не забыть переразмерить контейнер-приемник (вариант — не забыть использовать std::inserter)


Для подобных вещей есть assign, insert, и те же *inserter'ы.
И что именно значит "не забыть"? Видимо "не забыть" означает "нужно знать что делает используемый инструмент, а не использовать его наугад" — тогда да, нужно

_>что std::remove на самом деле не удаляет, а просто перетасовывает элементы


Ничего удивительного — std::remove работает с range'ами, а не с контейнерами. Принял range, и возвратил range (точнее два).

_>и то, что большинство библиотечных алгоритмов принимают кучку однотипных аргументов (подходя формально — "bad smell" в чистом виде) — это все не есть достоинства.


Что значит "кучку однотипных аргументов"?
Отредактировано 15.10.2014 17:14 Evgeny.Panasyuk . Предыдущая версия .
Re: Оцените решение задачи
От: Sni4ok  
Дата: 15.10.14 17:17
Оценка:
Здравствуйте, Ororo1, Вы писали:

решение ужасно, вы ожидаете выброс исключения:
vectors.at(i)

однако нигде его не перехватываете.
ну и в целом всё убого- скорость O(N^2) вместо напрашивающихся O(n * log(n))


O>Условие:

O>Даны 3 списка с числами. Числа в списках не повторяются. Сами списки отсортированы. Необходимо реализовать метод GetNext, который бы обходил все 3 списка и выдавал числа в порядке возрастания. Объединять списки нельзя!
O>Примеры списков:
O>[List]: 1, 5, 12, 28, 31
O>[List]: 6, 9, 13
O>[List]: 3, 7, 10, 15
O>Вывод в этом случае должен быть таким:
O>GetNext << 1;
O>GetNext << 3;
O>GetNext << 5;
O>GetNext << 6;
O>GetNext << 7;
O>GetNext << 9;
O>и т.д.

O>Решение:

O>
O>....

O>vector<vector<int>*> vectors;//тут хранятся наши списки

O>vector<int> vec1;
O>vector<int> vec2;
O>vector<int> vec3;//сами списки

O>....

O>vectors.push_back(&vec1);
O>vectors.push_back(&vec2);
O>vectors.push_back(&vec3);

O>vector<int> indexes(vectors.size(),0);//тут храним индекс элемента, который последний раз брали для каждого из списков

O>GetNext(indexes);
O>....


O>bool isExist(vector<int> &vec, int index)
O>{
O>    return index < vec.size();
O>}

O>int GetNext( vector<int> &indexes)
O>{
O>    int min = 0;
O>    int index = -1;
O>    for(int i=0;i<vectors.size();++i)
O>    {
O>        if(isExist(*vectors.at(i),indexes.at(i)))
O>        {
O>            min = vectors.at(i)->at(indexes.at(i));
O>            index = i;
O>            break;
O>        }
O>    }
    
O>    if(index == -1)
O>        throw exception();
    
O>    for(int i=0;i<vectors.size();++i)
O>    {
O>        if(isExist(*vectors.at(i),indexes.at(i)))
O>        {
O>            if(vectors.at(i)->at(indexes.at(i))<min)
O>            {
O>                min = vectors.at(i)->at(indexes.at(i));
O>                index = i;
O>            }
O>        }
O>    }
    
O>    indexes.at(index)++;
    
O>    return vectors.at(index)->at(indexes.at(index)-1);
    
O>}
O>
Re[2]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 17:23
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>ну и в целом всё убого- скорость O(N^2) вместо напрашивающихся O(n * log(n))


Откуда там квадратичная сложность?
Re[13]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 17:24
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>И что именно значит "не забыть"? и пр.


Это означает, что оно не интуитивно понятно трудно для понимания начинающему. И есть мнение, что все это можно было сделать проще и безопаснее за счет незначительных накладных расходов.


_>>и то, что большинство библиотечных алгоритмов принимают кучку однотипных аргументов (подходя формально — "bad smell" в чистом виде) — это все не есть достоинства.


EP>Что значит "кучку однотипных аргументов"?


template <class ForwardIterator1, class ForwardIterator2>
   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
                            ForwardIterator2 first2, ForwardIterator2 last2)


4 аргумента. И можно перепутать аргументы местами, и это скомпилируется без проблем. Да, это один из видов "bad smell" — слишком много аргументов.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Отредактировано 15.10.2014 17:27 slava_phirsov . Предыдущая версия .
Re[3]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 17:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

Не, главное, с чего там O(n * log2(n))?
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Отредактировано 15.10.2014 17:33 slava_phirsov . Предыдущая версия .
Re[14]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 17:34
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

_>И есть мнение, что все это можно было сделать проще и безопаснее за счет незначительных накладных расходов.


Например.

_>>>и то, что большинство библиотечных алгоритмов принимают кучку однотипных аргументов (подходя формально — "bad smell" в чистом виде) — это все не есть достоинства.

EP>>Что значит "кучку однотипных аргументов"?
_>
_>template <class ForwardIterator1, class ForwardIterator2>
_>   ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1,
_>                            ForwardIterator2 first2, ForwardIterator2 last2)
_>

_>4 аргумента. И можно перепутать аргументы местами, и это скомпилируется без проблем. Да, это один из видов "bad smell" — слишком много аргументов.

1. Четыре одинаковых итератора тут только в частном случае, а в общем — две пары разных итераторов.
2. Во всей библиотеке итераторы из одного range принимаются по порядку, запутаться трудно.
3. Какая альтернатива-то? Естественно без потери мощности в общем случае. Есть Boost.Range (или его аналог который войдёт в стандарт) — но это всего лишь оптимизация некоторых частных случаев.
Re[15]: Оцените решение задачи
От: slava_phirsov Россия  
Дата: 15.10.14 17:40
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:


EP>1. Четыре одинаковых итератора тут только в частном случае, а в общем — две пары разных итераторов.


Одна беда — поскольку типы итераторов являются параметрами шаблона, то типизация не помешает перепутать эти пары местами.

Что касается конкретно std::search, то ИМХО в большинстве случаев все четыре итератора будут одного типа.


EP>2. Во всей библиотеке итераторы из одного range принимаются по порядку, запутаться трудно.


Однако новички путаются. И даже — страшно сказать — забывают, надо ли ставить первым в паре begin или end. Да, со временем привыкают. Ну так о том и речь, что ножик-то слишком острый, чтобы намазывать им масло на хлеб, мог бы быть и потупее.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Отредактировано 15.10.2014 17:42 slava_phirsov . Предыдущая версия .
Re[16]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 18:02
Оценка:
Здравствуйте, slava_phirsov, Вы писали:

EP>>1. Четыре одинаковых итератора тут только в частном случае, а в общем — две пары разных итераторов.

_>Одна беда — поскольку типы итераторов являются параметрами шаблона, то типизация не помешает перепутать эти пары местами.

В таком случае даже Range версия не спасёт
template<class ForwardRange1, class ForwardRange2>
typename range_iterator<ForwardRange1>::type
search(ForwardRange1& rng1, const ForwardRange2& rng2);


_>Что касается конкретно std::search, то ИМХО в большинстве случаев все четыре итератора будут одного типа.


Согласен.

EP>>2. Во всей библиотеке итераторы из одного range принимаются по порядку, запутаться трудно.

_>Однако новички путаются. И даже — страшно сказать — забывают, надо ли ставить первым в паре begin или end. Да, со временем привыкают.

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

_>Ну так о том и речь, что ножик-то слишком острый, чтобы намазывать им масло на хлеб, мог бы быть и потупее.


Скоро будет в стандарте. А в библиотеках уже больше 10 лет.
Re[15]: Оцените решение задачи
От: PM  
Дата: 15.10.14 18:11
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

>3. Какая альтернатива-то? Естественно без потери мощности в общем случае. Есть Boost.Range (или его аналог который войдёт в стандарт) — но это всего лишь оптимизация некоторых частных случаев.


Аналог Boost.Range это https://github.com/ericniebler/range-v3 ? Выглядит многообещающе, еще бы попробовать их где-нибудь, но Visual C++ опять не поддерживается.

Блин, 15 лет прошло со времен плясок вокруг Visual C++ 6.0 в попытках заставить его компилировать шаблоны. Как будто ничего и не поменялось
Re[16]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 18:32
Оценка:
Здравствуйте, PM, Вы писали:

>>3. Какая альтернатива-то? Естественно без потери мощности в общем случае. Есть Boost.Range (или его аналог который войдёт в стандарт) — но это всего лишь оптимизация некоторых частных случаев.

PM>Аналог Boost.Range это https://github.com/ericniebler/range-v3 ?

Я не следил за предложениями, может там и другие proposals были.

PM>Блин, 15 лет прошло со времен плясок вокруг Visual C++ 6.0 в попытках заставить его компилировать шаблоны. Как будто ничего и не поменялось


Какое-то движение всё же есть. Они хоть и отстают, но уже стараются догонять.
Кстати, ЕМНИП Саттер (или Стефан) не так давно говорил, что они вот-вот начнут внутри компилятора использовать AST

P.S. Помимо Boost.Range ещё есть и аналог в Adobe.ASL
Re[17]: Оцените решение задачи
От: PM  
Дата: 15.10.14 19:00
Оценка: 9 (1)
Здравствуйте, Evgeny.Panasyuk, Вы писали:

>>>3. Какая альтернатива-то? Естественно без потери мощности в общем случае. Есть Boost.Range (или его аналог который войдёт в стандарт) — но это всего лишь оптимизация некоторых частных случаев.

PM>>Аналог Boost.Range это https://github.com/ericniebler/range-v3 ?

EP>Я не следил за предложениями, может там и другие proposals были.


Я тоже не слежу за предложениями, просто читаю http://ericniebler.com, Eric там пишет о своих успехах

PM>>Блин, 15 лет прошло со времен плясок вокруг Visual C++ 6.0 в попытках заставить его компилировать шаблоны. Как будто ничего и не поменялось


EP>Какое-то движение всё же есть. Они хоть и отстают, но уже стараются догонять.

EP>Кстати, ЕМНИП Саттер (или Стефан) не так давно говорил, что они вот-вот начнут внутри компилятора использовать AST

Прогресс есть, реально в VS 2013 не хватет только constexpr из-за отсутствия которого самые современные библиотеки не поддерживаются. Я с Boost.Hana так пролетел, вот и ворчу


EP>P.S. Помимо Boost.Range ещё есть и аналог в Adobe.ASL


Да, только давненько оно не обновлялось.

Кстати недавно Eric победил проблему с производительностью counted ranges на которую указывал Sean Parent (я так понимаю он автор ranges в ASL). Результатом и стало предложение D4128 Ranges for the Standard Library: Revision 1. В нем помимо изменений в стандартной библиотеке предлагается немного поменять семантику range-based for loop чтобы begin и end могли быть разными типами. Так что в Visual C++ 2020 может быть увидим что-нибудь
Re[3]: Оцените решение задачи
От: alzt  
Дата: 15.10.14 19:09
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

К>>- сделать не на векторах, а по-честному, на списках

К>>- на изменяемых списках это даже проще делается

EP>А зачем? Тормозить ведь будет. Это же не merge списков в один большой, а просто вывод по отдельности каждого элемента.

EP>Вот если бы в результате нужен был список — то другое дело, действительно проще и быстрее собрать из трёх связанных списков один большой.

А с чего тормозить-то будет? Списки/векторы уже отсортированы, от них требуется только операция продвижения итератора вперёд.
Re[4]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 19:16
Оценка: +1 -1
Здравствуйте, alzt, Вы писали:

К>>>- сделать не на векторах, а по-честному, на списках

К>>>- на изменяемых списках это даже проще делается
EP>>А зачем? Тормозить ведь будет. Это же не merge списков в один большой, а просто вывод по отдельности каждого элемента.
EP>>Вот если бы в результате нужен был список — то другое дело, действительно проще и быстрее собрать из трёх связанных списков один большой.
A>А с чего тормозить-то будет? Списки/векторы уже отсортированы, от них требуется только операция продвижения итератора вперёд.

Линейный обход связного списка в общем случае на порядок(и) дороже чем соответствующий обход вектора. Если в задаче не указанно что нужен именно связный список, то по-умолчанию нужно брать vector.
Re[18]: Оцените решение задачи
От: Evgeny.Panasyuk Россия  
Дата: 15.10.14 20:02
Оценка: 6 (1)
Здравствуйте, PM, Вы писали:

PM>Прогресс есть, реально в VS 2013 не хватет только constexpr из-за отсутствия которого самые современные библиотеки не поддерживаются. Я с Boost.Hana так пролетел, вот и ворчу


А что Hana даёт по сравнению с Boost.Fusion? Только скорость компиляции?

PM>Кстати недавно Eric победил проблему с производительностью counted ranges


Спасибо за ссылку.
Но ведь не побелил же! Его концепция CountedRange выглядит как хак, который к тому же жертвует производительностью. Если бы не было потерь производительности, то можно было бы и пережить, а с потерями — ну уж нет.
ИМХО, не нужно боятся вводить новые концепции Range'ей — если эти концепции чётко улавливают суть, позволяя писать эффективный код (в абсолютном смысле, а не "в этом вот примере всего 5%" разница). Не хаки-адапторы к старым алгоритмам, а полноценные range со своими оптимизированными алгоритмами, как раз наподобие partition_point_n.

PM>на которую указывал Sean Parent (я так понимаю он автор ranges в ASL).


Он, кстати, раньше работал со Степановым.

Кстати, вот в этом моменте Степанов рассказывает про Counted Range.
А вот тут про двумерные итераторы (Eric упоминал их как segmented).
Re[2]: Оцените решение задачи
От: sokel Россия  
Дата: 16.10.14 07:00
Оценка: +1
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вот тут
Автор: Lazin
Дата: 10.07.14
было обсуждение подобной задачи.

EP>В частности, простое решение выглядит вот так:
EP>
EP>while(!q.empty())
EP>{
EP>    auto range = heap.top();  
EP>    q.pop();

EP>    //assert(!empty(range));
EP>    *out++ = *begin(range);
EP>    range = make_iterator_range(next(begin(range)), end(range));
EP>    if(!empty(range))
EP>        q.push(range);
EP>}
EP>

EP>Легко приводится к интерфейсу GetNext.

ага, как то так наверное:
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;

typedef vector<int> list_type;

void print(const vector<list_type>& in) {
    using list_iter = pair < list_type::const_iterator, list_type::const_iterator >;
    using iter_state = vector < list_iter >;
    iter_state iters;
    iters.reserve(in.size());
    for(auto& l : in)
        if(!l.empty())
            iters.push_back({ l.begin(), l.end() });

    auto iter_compare = [](const list_iter& i1, const list_iter& i2) {
        return *i1.first > *i2.first;
    };
    make_heap(iters.begin(), iters.end(), iter_compare);
    while(!iters.empty()) {
        pop_heap(iters.begin(), iters.end(), iter_compare);
        list_iter& min = iters.back();
        cout << *min.first << endl;
        ++min.first;
        if(min.first == min.second)
            iters.pop_back();
        else
            push_heap(iters.begin(), iters.end(), iter_compare);
    }
}

int main(int argc, char* argv[])
{
    vector<list_type> lists = {
            { 1, 5, 12, 28, 31 },
            { 6, 9, 13 },
            { 3, 7, 10, 15 }
    };
    print(lists);
    return 0;
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.