update sequence items
От: EvilChild Ниоткуда  
Дата: 06.09.06 09:35
Оценка:
Дано:
    vector<int> iv;
    iv.push_back(5);
    iv.push_back(3);
    iv.push_back(1);
    iv.push_back(2);

Нужно используя только средства стандартной библиотеки (не кодируя цикл явно) инкрементировать каждый элемент вектора.
Это вообще реально?
Или нужно как минимум свой функтор писать?
now playing: Silent Witness — Ringside (Vicious Circle Remix)
Re: update sequence items
От: Smal Россия  
Дата: 06.09.06 09:39
Оценка:
Здравствуйте, EvilChild, Вы писали:

EC>Дано:

EC>
EC>    vector<int> iv;
EC>    iv.push_back(5);
EC>    iv.push_back(3);
EC>    iv.push_back(1);
EC>    iv.push_back(2);
EC>

EC>Нужно используя только средства стандартной библиотеки (не кодируя цикл явно) инкрементировать каждый элемент вектора.
EC>Это вообще реально?
EC>Или нужно как минимум свой функтор писать?

Что-то вроде.
std::transform( iv.begin(), iv.end(), iv.begin(), std::bind1st( std::add<int>(), 1 ) );
С уважением, Александр
Re[2]: update sequence items
От: Smal Россия  
Дата: 06.09.06 09:40
Оценка: 5 (2)
Здравствуйте, EvilChild, Вы писали:

S>Что-то вроде.

S>std::transform( iv.begin(), iv.end(), iv.begin(), std::bind1st( std::add<int>(), 1 ) );

В смысле
std::transform( iv.begin(), iv.end(), iv.begin(), std::bind1st( std::plus<int>(), 1 ) );
С уважением, Александр
Re[3]: update sequence items
От: Аноним  
Дата: 06.09.06 10:36
Оценка:
Здравствуйте, Smal, Вы писали:

S>Здравствуйте, EvilChild, Вы писали:


S>>Что-то вроде.

S>>std::transform( iv.begin(), iv.end(), iv.begin(), std::bind1st( std::add<int>(), 1 ) );

S>В смысле

S>std::transform( iv.begin(), iv.end(), iv.begin(), std::bind1st( std::plus<int>(), 1 ) );

мда... а бы в этом случае всеже лучше цикл использовал...
Re[4]: update sequence items
От: EvilChild Ниоткуда  
Дата: 06.09.06 10:55
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>мда... а бы в этом случае всеже лучше цикл использовал...

Сравни длину конструкций:
for (vector<int>::iterator it = iv.begin(); it != iv.end(); ++it)
{
    *it += 1;
}

и
transform(iv.begin(), iv.end(), iv.begin(), bind1st(plus<int>(), 1));

Во второй не нужно придумывать имена переменным и нет адресной арифметики.
now playing: Silent Witness & Break — The Question
Re[5]: update sequence items
От: Аноним  
Дата: 06.09.06 11:11
Оценка: +1 :))
Здравствуйте, EvilChild, Вы писали:

EC>Здравствуйте, <Аноним>, Вы писали:


А>>мда... а бы в этом случае всеже лучше цикл использовал...

EC>Сравни длину конструкций:
EC>
EC>for (vector<int>::iterator it = iv.begin(); it != iv.end(); ++it)
EC>{
EC>    *it += 1;
EC>}
EC>

EC>и
EC>
EC>transform(iv.begin(), iv.end(), iv.begin(), bind1st(plus<int>(), 1));
EC>

EC>Во второй не нужно придумывать имена переменным и нет адресной арифметики.

а если так:

for( vector<int>::iterator it = iv.begin(); it != iv.end(); ++it ) *it += 1;

и так:

transform(
iv.begin(), iv.end(), iv.begin(),
bind1st(plus<int>(), 1)
);


Re[6]: update sequence items
От: Аноним  
Дата: 06.09.06 11:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, EvilChild, Вы писали:


EC>>Здравствуйте, <Аноним>, Вы писали:


А>>>мда... а бы в этом случае всеже лучше цикл использовал...

EC>>Сравни длину конструкций:
EC>>
EC>>for (vector<int>::iterator it = iv.begin(); it != iv.end(); ++it)
EC>>{
EC>>    *it += 1;
EC>>}
EC>>

EC>>и
EC>>
EC>>transform(iv.begin(), iv.end(), iv.begin(), bind1st(plus<int>(), 1));
EC>>

EC>>Во второй не нужно придумывать имена переменным и нет адресной арифметики.

А>а если так:


А>for( vector<int>::iterator it = iv.begin(); it != iv.end(); ++it ) *it += 1;


А>и так:


А>transform(

А> iv.begin(), iv.end(), iv.begin(),
А> bind1st(plus<int>(), 1)
А>);


А>


на самом деле я бы написал тут вообще вот так. и это имхо было _правильно_ в данном случае:

    for( int i = 0; i < iv.size(); i++ ) 
        ++iv[i];


все предельно просто и понятно. и компильнется быстрее.
Re[6]: update sequence items
От: Roman Odaisky Украина  
Дата: 06.09.06 11:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>мда... а бы в этом случае всеже лучше цикл использовал...

EC>>Сравни длину конструкций:
EC>>
EC>>for (vector<int>::iterator it = iv.begin(); it != iv.end(); ++it)
EC>>{
EC>>    *it += 1;
EC>>}
EC>>

EC>>и
EC>>
EC>>transform(iv.begin(), iv.end(), iv.begin(), bind1st(plus<int>(), 1));
EC>>

EC>>Во второй не нужно придумывать имена переменным и нет адресной арифметики.

А>а если так:


А>
for( vector<int>::iterator it = iv.begin(); it != iv.end(); ++it ) *it += 1;


А>и так:


А>
transform(
  iv.begin(), iv.end(), iv.begin(), 
  bind1st(plus<int>(), 1)
);


Тогда уже так:
foreach(int& x, iv) ++x;
До последнего не верил в пирамиду Лебедева.
Re[7]: update sequence items
От: Roman Odaisky Украина  
Дата: 06.09.06 11:31
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>на самом деле я бы написал тут вообще вот так. и это имхо было _правильно_ в данном случае:


А>
А>    for( int i = 0; i < iv.size(); i++ ) 
А>        ++iv[i];
А>


А>все предельно просто и понятно. и компильнется быстрее.


Правильно тут использовать не int, а std::size_t. И то не очень. Код с for(C::iterator) будет работать для любого контейнера, даже для iterator_range<istream_iterator>, — после соответствующей замены типа итератора. Код с transform (как и foreach, кстати), может быть использован для любого контейнера без единой замены. Код же с индексом годится только для vector/deque, причем для второго падает эффективность. Читаемость всех 4 вариантов одинакова для сколько-нибудь опытного программера, эффективность (пока у нас всё еще std::vector) одинакова для сколько-нибудь вменяемого оптимизатора. Выводы?
До последнего не верил в пирамиду Лебедева.
Re[8]: update sequence items
От: Аноним  
Дата: 06.09.06 11:42
Оценка: +1
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, Аноним, Вы писали:


А>>на самом деле я бы написал тут вообще вот так. и это имхо было _правильно_ в данном случае:


А>>
А>>    for( int i = 0; i < iv.size(); i++ ) 
А>>        ++iv[i];
А>>


А>>все предельно просто и понятно. и компильнется быстрее.


RO>Правильно тут использовать не int, а std::size_t. И то не очень. Код с for(C::iterator) будет работать для любого контейнера, даже для iterator_range<istream_iterator>, — после соответствующей замены типа итератора. Код с transform (как и foreach, кстати), может быть использован для любого контейнера без единой замены. Код же с индексом годится только для vector/deque, причем для второго падает эффективность. Читаемость всех 4 вариантов одинакова для сколько-нибудь опытного программера, эффективность (пока у нас всё еще std::vector) одинакова для сколько-нибудь вменяемого оптимизатора. Выводы?


выводы такие, что тут делается "экстросенсорные" предположения о том, что этот код будет использоваться именно в других контейнерах, а не для развитеия самого алгоритма. как правило не контейнер меняется, а развивается сам алгоритм, например мне надо будет не увеличивать на единицу, а применять более сложную формулу, модифицировать только часть массива и т.п. вот это более реально имхо, чем если контейнер с вектора вдруг поменяется на лист. ы? и что проще, быстрее, надежней будет в этом случае?
Re[9]: update sequence items
От: Roman Odaisky Украина  
Дата: 06.09.06 15:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>выводы такие, что тут делается "экстросенсорные" предположения о том, что этот код будет использоваться именно в других контейнерах, а не для развитеия самого алгоритма. как правило не контейнер меняется, а развивается сам алгоритм, например мне надо будет


А>не увеличивать на единицу, а применять более сложную формулу

Так это же не зависит от способа хождения по массиву.

А>модифицировать только часть массива и т.п.

Тогда однозначно пара итераторов.
До последнего не верил в пирамиду Лебедева.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.