Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
fuzzytoozy
8 / 8 / 1
Регистрация: 23.11.2012
Сообщений: 94
#1

STL. Алгоритм copy() - C++

17.04.2013, 19:34. Просмотров 1915. Ответов 6
Метки нет (Все метки)

Здравствуйте. Решаю задачку из учебника лафоре. Звучит она следующим образом:

Алгоритм copy() можно использовать для копирования последовательностей в контейнере. Тем не менее нужно внимательно следить за тем, чтобы целевая последовательность не перекрывала исходную. Напишите программу, позволяющую производить копирование последовательностей внутри контейнера. Допустим, пользователь вводит значения first1, last1 и first2. Осуществляйте в программе проверку того, что последовательность, перекрывающая другую, сдвигается налево, а не направо. ( Например, можно сдвигать некоторые данные из позиции 10 в позицию 9, но не в позицию 11) Так делается потому, что copy() начинает работу с крайнего элемента слева.

Не знаю к кому обратиться. Я абсолютно не понимаю о чем тут речь, куда сдвигать и что? Алгоритм copy ничего не сдвигает, он ведь просто заменяет одни данные другими, даже в случае, если мы используем итератор вставки, чтобы контролировать процесс сдвига данных нужно редактировать исходный код алгоритма.В любом случае я не вижу причины делать этого. Я не понимаю, что от меня хочет автор этой задачи, хоть тресни. Может кто пожалуйста разжевать в чем соль? Я бы сделал его сам но я не понимаю задания.... =(
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1605 / 997 / 118
Регистрация: 27.09.2009
Сообщений: 1,923
Завершенные тесты: 1
17.04.2013, 19:41     STL. Алгоритм copy() #2
Поясню на простом примере. Допустим, у нас есть массив размером в 20 элементов. И нам надо переместить участок [5; 15) в участок [7;17). Если мы воспользуемся copy, то мы перезапишем сначала 7 элемент 5-м, потом 8-й шестым, а дальше будем читать в качестве исходных данных уже перезаписанный 7-й, перенося его в 9-й. Таким образом, вместо аккуратного переноса участка мы размножим два первых элемента на весь интервал. Видимо, Лафоре предлагает отслеживать такие ситуации и пользоваться в таком случае либо copy_backward, либо обычным copy на reverse_iterator.
fuzzytoozy
8 / 8 / 1
Регистрация: 23.11.2012
Сообщений: 94
17.04.2013, 20:20  [ТС]     STL. Алгоритм copy() #3
Цитата Сообщение от Nick Alte Посмотреть сообщение
а дальше будем читать в качестве исходных данных уже перезаписанный 7-й, перенося его в 9-й
совершенно не понял смысл этого предложения. Почему будем считать в качестве исходных данных 7й элемент, да еще и переносить его в 9й? У меня что то туго совсем с этим.

Добавлено через 12 минут
Может кто нибудь на примере этого кода разжевать, что делают алгоритм copy и алгоритм copy_backward и в чем их принципиальное отличие. А так же объяснить подробно, что хотел автор в этой задаче.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//---------------------------------------------------------------------------
 
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
//---------------------------------------------------------------------------
 
int main(int argc, char* argv[])
{
 vector<int> v1;
 vector<int> v2;
 vector<int>::iterator iter1;
 vector<int>::iterator iter2;
 
 for(int j =1; j < 10; j++)
        v1.push_back(j);
 
 v2 = v1;
 cout << "\n Vector: ";
 for ( iter1 = v1.begin(); iter1 != v1.end(); iter1++ )
        cout << *iter1 << ' ';
 cout << endl;
 
 
 iter1 = v1.begin();
 iter2 = v2.begin();
 
 copy(iter1, iter1+3, iter1+6);
 copy_backward(iter2, iter2+3,iter2+6);
 
 
 
 cout << "\n Changed Vector1: ";
 for (iter1 = v1.begin(); iter1 != v1.end(); iter1++ )
        cout << *iter1 << ' ';
 cout << endl;
 cout <<"\n Changed Vector2: ";
 for ( iter2 = v2.begin(); iter2 != v2.end(); iter2++)
        cout << *iter2 << ' ';
 
 cout << endl;
 
 
 system("PAUSE");
        return 0;
}
//---------------------------------------------------------------------------
Jupiter
Каратель
Эксперт С++
6550 / 3970 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
17.04.2013, 22:23     STL. Алгоритм copy() #4
Цитата Сообщение от fuzzytoozy Посмотреть сообщение
совершенно не понял смысл этого предложения. Почему будем считать в качестве исходных данных 7й элемент, да еще и переносить его в 9й? У меня что то туго совсем с этим.
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|
1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|
участки перекрываются, а коллекция то одна и та же
"Если мы воспользуемся copy, то мы перезапишем сначала 7 элемент 5-м, потом 8-й шестым",
а дальше мы скопируем 7-й элемент в 9-й, но в мы же только что в 7-й уже записали 5-ку.

Добавлено через 30 минут
Цитата Сообщение от fuzzytoozy Посмотреть сообщение
Может кто нибудь на примере этого кода разжевать, что делают алгоритм copy и алгоритм copy_backward и в чем их принципиальное отличие. А так же объяснить подробно, что хотел автор в этой задаче.
если трудно понять пример, подставь более просты числа
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
 
int main()
{
    std::vector<int> vec1(9);
    std::vector<int> vec2;
 
    for(int j = 1; j < 10; ++j)
        vec2.push_back(j);
 
    std::cout << "Before changes:" << std::endl;
    std::copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
    std::copy(vec2.begin(), vec2.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
 
    std::copy(vec2.begin(), vec2.begin() + 4, vec1.begin());
    std::cout << "After copy:" << std::endl;
    std::copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
 
    std::copy_backward(vec2.begin(), vec2.begin() + 4, vec1.end());
    std::cout << "After copy_backward:" << std::endl;
    std::copy(vec1.begin(), vec1.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << std::endl;
}
copy(a, b, c) - копирует элементы из диапазона [a, b) слева направо в диапазон [c, c + b -a)
copy_backward(a, b, c) - копирует элементы из диапазона [a, b) справа налево в диапазон [c - b + a, c)
sWINo_BACK_LAN
5 / 5 / 0
Регистрация: 30.03.2016
Сообщений: 26
30.03.2016, 13:39     STL. Алгоритм copy() #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
 
int _tmain(int argc, _TCHAR* argv[])
{
    vector<int> v(20);
    vector<int>::iterator iter;
    int c = 1;
    for(iter = v.begin();iter<v.end();iter++)
    {
        *iter = c;
        c++;
    }
    cout<<"Ishodnii massiv:"<<endl;
    cout<<"|";
    for(iter = v.begin();iter<v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
    iter = v.begin();
    copy(iter+5,iter+15,iter+7);
    cout<<"Obrabotannii massiv:"<<endl;
    cout<<"|";
    for(iter = v.begin();iter<v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
    iter = v.begin();
    cin.get();
    cin.get();
    return 0;
}
этот код выдает результат:
Ishodnii massiv:
|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|
Obrabotannii massiv:
|1|2|3|4|5|6|7|6|7|8|9|10|11|12|13|14|15|18|19|20|
то есть, просто, копи диапазона с перекрытием без всяких извратов,но, лупинга 5 и 6 элементов не происходит по всему диапазону,видимо, алгоритм, все - таки, перед замещением буферизует целевую последовательность всю как она есть, а, потом перезаписывает(студия 2010)
Croessmah
Модератор
Эксперт CЭксперт С++
12889 / 7275 / 811
Регистрация: 27.09.2012
Сообщений: 17,974
Записей в блоге: 2
Завершенные тесты: 1
30.03.2016, 14:09     STL. Алгоритм copy() #6
Цитата Сообщение от sWINo_BACK_LAN Посмотреть сообщение
то есть, просто, копи диапазона с перекрытием без всяких извратов
Если у Вас POD-тип, и соответствующие итераторы,
то может быть использован, например, memmove,
который может копировать перекрывающиеся диапазоны.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <vector>
#include <algorithm>
#include <type_traits>
using namespace std;
 
 
 
 
struct Test
{
    Test& operator=(int x_){
        x= x_;
        return *this;
    }
    int x;
};
 
 
 
std::ostream& operator<<(std::ostream &stream, const Test &test)
{
    return stream << test.x ;
    
}
 
 
 
int main()
{
    std::cout << (std::is_pod<Test>::value?"":"non-") << "pod type"<< std::endl;
    vector<Test> v(20);
    vector<Test>::iterator iter;
    int c = 1;
    for(iter = v.begin();iter!=v.end();iter++)
    {
        *iter = c;
        c++;
    }
    
    cout<<"Ishodnii massiv:"<<endl;
    cout<<"|";
    
    for(iter = v.begin();iter!=v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
    
    iter = v.begin();
    copy(iter+5,iter+15,iter+7);
    
    cout<<"Obrabotannii massiv:"<<endl;
    cout<<"|";
    for(iter = v.begin();iter!=v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
}
http://rextester.com/TAS36876

А если у Вас non-pod тип, то уже получите то, что хотели:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//g++  4.9.3
 
#include <iostream>
#include <vector>
#include <algorithm>
#include <type_traits>
using namespace std;
 
 
 
 
struct Test
{
    Test():x(0){}
    Test(const Test& src){
        std::cout << "Copy Test(" << src.x << ")[" << (void*)&src << "] to Test(" << x << ")[" << (void*)this << "]" << std::endl;
        x = src.x;
    }
    
    
    Test& operator=(const Test& src){
        std::cout << "Assignment Test(" << src.x << ")[" << (void*)&src << "] to Test(" << x << ")[" << (void*)this << "]" << std::endl;
        x = src.x;
        return *this;
    }
    
    
    Test& operator=(int x_){
        x= x_;
        return *this;
    }
    int x;
};
 
 
 
std::ostream& operator<<(std::ostream &stream, const Test &test)
{
    return stream << test.x ;
    
}
 
 
 
int main()
{
    std::cout << (std::is_pod<Test>::value?"":"non-") << "pod type"<< std::endl;
    vector<Test> v(20);
    vector<Test>::iterator iter;
    int c = 1;
    for(iter = v.begin();iter!=v.end();iter++)
    {
        *iter = c;
        c++;
    }
    
    cout<<"Ishodnii massiv:"<<endl;
    cout<<"|";
    
    for(iter = v.begin();iter!=v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
    
    iter = v.begin();
    copy(iter+5,iter+15,iter+7);
    
    cout<<"Obrabotannii massiv:"<<endl;
    cout<<"|";
    for(iter = v.begin();iter!=v.end();iter++)
        cout<<*iter<<"|";
    cout<<endl;
}
http://rextester.com/WMEI62144
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.03.2016, 20:58     STL. Алгоритм copy()
Еще ссылки по теме:

C++ Алгоритм copy
Алгоритм copy и итераторы вставки C++
Std::move stl-алгоритм C++
C++ Продемонстрировать работу алгоритмов STL copy, и max_element
C++ Алгоритм copy, back_inserter и vector

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

Или воспользуйтесь поиском по форуму:
sWINo_BACK_LAN
5 / 5 / 0
Регистрация: 30.03.2016
Сообщений: 26
30.03.2016, 20:58     STL. Алгоритм copy() #7
пока не знаю таких типов,тоже лафоре читаю,завтра посмотрю подробнее ваш код,сегодня уже времени много...
ЗЫ:оглядываясь назад,скажу:Лафоре отличная книга для изучения языка,но,главу про STL по этой книге изучать крайне противопоказано!!!!Этот раздел у Роберта отвратно изъяснен,только,запутает,по STL надо какую - то другую отдельную книжку скачать и пройтись,тема далеко не на 20 страниц,даже,не на 200!
Yandex
Объявления
30.03.2016, 20:58     STL. Алгоритм copy()
Ответ Создать тему
Опции темы

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