Data+

14. STL list2

by Qerogram

* list erase

- erase 방법에는 2가지가 있다.

- 아래의 코드는 2가지 방법 모두 사용해서 구현했다.

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 <iostream>
#include <list>
using namespace std;
 
int main(int argc, char* argv[]) {
  list<int> list1;
  list1.push_back(10);
  list1.push_back(20);
  list1.push_back(30);
  list1.push_back(40);
  list1.push_back(50);
  
  cout << "erase 테스트1" << endl;
  
  list1.erase(list1.begin());
  list<int>::iterator iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1 : " << *iterPos << endl;
  }
  
  cout << endl << "erase 테스트2" << endl;
  list<int>::iterator iterPos = list1.begin();
  list1.erase(++iterPos, list1.end());
  iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1 : " << *iterPos << endl;
  }
  return 0;
}
cs

* 결과

erase 테스트1
list 1 : 20
list 1 : 30
list 1 : 40
list 1 : 50

erase 테스트2
list 1 : 20


* list 반복자의 랜덤 접근

- 위의 코드에서 2번째 위치에 접근하기 위해 ++iterPos를 하였는데 세번째 위치까지 가려하면 한번 더 해야된다.

- list는 랜덤 접근이 불가능하지만, vector와 같이 랜덤 접근이 가능한 컨테이너는 iterPos = vector.begin() + 3;과 같이 가능하다.

- 반복문에서 list의 데이터를 삭제하면서 반복하는 경우 조심하지 않으면 버그가 쉽게 발생한다.

- 3의 배수를 리스트에서 지우는 것을 해보면 아래의 코드와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <list>
using namespace std;
 
int main(int argc, char* argv[]) {
  list<int> list1;
  list1.push_back(10);
  list1.push_back(20);
  list1.push_back(30);
  list1.push_back(40);
  list1.push_back(50);
  
  list<int>::iterator iterPos = list1.begin();
  while(iterPos != list1.end() ) {
    if(0 == (*iterPos%3)) {
      iterPos = list1.erase(iterPos);
      continue;
    }
    cout << "list1 : " << *iterPos <<endl;
    ++iterPos;
  }
  return 0;
}
cs

* 결과

list1 : 10
list1 : 20
list1 : 40
list1 : 50


* list remove

- list에서 지정한 값과 일치하는 모든 데이터를 지운다.

- erase와의 차이 : erase는 iterator를 통해 삭제를 하지만, remove는 값을 통해 삭제를 한다.

- struct나 class의 pointer를 담고 있다면, 삭제를 원하는 struct의 pointer를 통해서 삭제해야한다.

- 이미 정의된 자료형만 삭제할 수 있는 것이 아니라, 사용자 정의 타입이라도 포인터로 담으면 해당 포인터로 삭제가 가능하다.


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
#include <iostream>
#include <list>
 
using namespace std;
 
struct Item {
  Item(int itemCd, int buyMoney) {
    ItemCd = itemCd; 
    BuyMoney = buyMoney;
  }
  int ItemCd;
  int BuyMoney;
};
 
int main(int argc, char* argv[]) {
  list<int> list1;
  list1.push_back(10);
  list1.push_back(20);
  list1.push_back(30);
  list1.push_back(40);
  
  list<int>::iterator iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1 : " << *iterPos << endl;
  }
  
  cout << endl << "remove 테스트1" << endl;
  list1.remove(20);
  
  iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1 : " << *iterPos << endl;
  }
  
  cout << endl << "remove 테스트2(구조체 삭제)" << endl;
  list<Item*> Itemlist;
  Item* pitem1 = new Item(10100); Itemlist.push_back(pitem1);
  Item* pitem2 = new Item(20200); Itemlist.push_back(pitem2);
  Item* pitem3 = new Item(30300); Itemlist.push_back(pitem3);
  
  Itemlist.remove(pitem2);
  
  list<Item*>::iterator iterEnd2 = Itemlist.end();
  for(list<Item*>::iterator iterPos = Itemlist.begin(); iterPos!=iterEnd2; ++iterPos) {
    cout << "Itemlist : " << (*iterPos)->ItemCd << endl;
  }
  return 0;
}
cs

* 결과

list 1 : 10
list 1 : 20
list 1 : 30
list 1 : 40

remove 테스트1
list 1 : 10
list 1 : 30
list 1 : 40

remove 테스트2(구조체 삭제)
Itemlist : 10
Itemlist : 30


* remove_if

- 지정한 조건의 함수 객체(Predicate)를 만족하는 모든 데이터 삭제

- remove와의 차이는 함수 객체를 사용하여 parameter로 전달된 인자를 조사하여 true라면 삭제

- unary_function은 인자없이 호출되는 단항함수이다. 자세한 설명은 추후에 달겠다.

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
#include <iostream>
#include <list>
using namespace std;
 
template <typename T> class Is_Over20_Under30: public unary_function<T, bool> {
  public :
    bool operator() (T& val) {
      return (val >=20 && val < 30);
    }
};
 
int main() {
  list<int> list1;
  list1.push_back(10);
  list1.push_back(20);
  list1.push_back(30);
  list1.push_back(40);
  list1.push_back(50);
  
  list1.remove_if(Is_Over20_Under30<int>());
  list<int>::iterator iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1: " << *iterPos << endl;
  }
  
  return 0;
}
cs

* 결과

list 1: 10
list 1: 30
list 1: 40
list 1: 50


* sort

- 내림차순의 경우, greater<>()를 통해 가능하다. (x > y) ? true : false;

- 그 이외에도 greater_equal, less_equal도 존재한다.

- 사용자 정의 함수를 정렬 하려면 함수 객체를 만들어야한다.(ItemCd값으로 정렬 했다)


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
#include <iostream>
#include <list>
 
using namespace std;
 
template <typename T> struct COMPARE_ITEM {
  bool operator()(const T l, const T r) const {
    return l.ItemCd < r.ItemCd;
  }
};
 
struct Item {
  Item(int itemCd, int buyMoney) {
    ItemCd = itemCd;
    BuyMoney = buyMoney;
  }
  int ItemCd;
  int BuyMoney;
};
 
int main() {
  list<int> list1;
  list1.push_back(20);
  list1.push_back(10);
  list1.push_back(35);
  list1.push_back(15);
  list1.push_back(12);
  
  cout << "sort 오름차순" << endl;
  list1.sort();
  
  list<int>::iterator iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos!=iterEnd; ++iterPos) {
    cout <<"list1 : " << *iterPos << endl;
  }
  
  cout << endl << "sort 내림차순" << endl;
  list1.sort(greater<int>());
  iterEnd = list1.end();
  for(list<int>::iterator iterPos = list1.begin(); iterPos != iterEnd; ++iterPos) {
    cout << "list 1 : " << *iterPos << endl;
  }
  
  cout << endl << "sort 사용자 정의 방식 정렬" << endl;
  
  list<Item> Itemlist;
  Item item1(20100); Itemlist.push_back(item1);
  Item item2(10200); Itemlist.push_back(item2);
  Item item3(7300); Itemlist.push_back(item3);
  
  Itemlist.sort(COMPARE_ITEM<Item>());
  list<Item>::iterator iterEnd2 = Itemlist.end();
  for(list<Item>::iterator iterPos = Itemlist.begin(); iterPos!=iterEnd2; ++iterPos) {
    cout << "Itemlist : " << iterPos->ItemCd << endl;
  }
  return 0;
}
 
cs


* 결과

sort 오름차순
list1 : 10
list1 : 12
list1 : 15
list1 : 20
list1 : 35

sort 내림차순
list 1 : 35
list 1 : 20
list 1 : 15
list 1 : 12
list 1 : 10

sort 사용자 정의 방식 정렬
Itemlist : 7
Itemlist : 10
Itemlist : 20


* 참고 - Thinking About C++ STL Programming

'코딩 > C&C++' 카테고리의 다른 글

16. STL vector1  (0) 2017.04.17
15. STL list3  (0) 2017.04.17
13. STL list1  (0) 2017.04.15
12. 클래스 템플릿의 이해3  (0) 2017.04.15
11. 클래스 템플릿의 이해2  (0) 2017.04.15

블로그의 정보

Data+

Qerogram

활동하기