GSI

stl 문중에서 아마도 vector를 가장 개인적으로 선호 한다.
이론적인 내용은 우선 접어 두고.. (책을 보면 안다 ^^)

기존에 내가 했던 작업은 vector와 for문을 많이 사용했다.
이번에 accumulate, for_each를 공부 하면서 많은 부분 간소화 시키고
가독성과 범용성을 갖출수 있는 방법을 찾아 봤다.
class 의 객체를 vector에 추가 해서 작업 할때 vector의 배열 정보를 사용해서
특정 변수의 값을 다르게 변경할 작업이 많이 생긴다.

//헤더에 필요한 헤더파일을 추가한다.

#include <vector>
#include <map>
#include <algorithm>
#include <numeric>

using namespace std;

아래와 같은 클래스가 있다고 하자.

class Element {
public:
 DWORD UID;
 INT  Price;
 int  Count;
 DWORD Res_ID;

 //생성자
 Element(DWORD uid, INT price, int count, DWORD res_id, ) :
  UID(uid),
  Price(price),
  Count(count),
  Res_ID(res_id),
 {
 }

 //operator
 bool operator==(const Element& e) const {
  return (UID == e.UID) ? true : false;
 }
};

위의 코드에서 price는 가격을 뜻하고, count는 수량을 뜻한다.
Res_ID는 해당 오브젝트의 리소스 아이디라고 가정을 하자.
아래와 같은 작업을 할려고 한다.

1. Count가 음수인 요소들의 개수를 얻어 오고 싶다.
2. Count가 음수인 요소들의 Price의 총 합을 얻고 싶다.
3. Count가 음수인 요소들의 Res_ID의 목록을 얻고 싶다.

기존에 for문을 사용하게 되면 코드의 량도 늘어 나고 보기에도 좀 그렇다.
아래와 같은 accumulate 함수를 작성하고 활용하면 자연스럽게 구현이 가능하다.

//카운터가 0보다 작은 요소들의 개수
int count_minus_element_sum (int count, const Element& t1 ) {
 if(t1.Count < 0)
  count++;

 return count;
}

//카운터가 0보다 작은 요소들의 총금액
int count_minus_element_price_sum (int price, const Element& t1 )
{
 if(t1.Count < 0) {
  price += (abs(t1.Count) * t1.Price);
 }

 return price;
}

//카운터가 0보다 작은 resid를 추출
vector<DWORD>& count_minus_resid ( vector<DWORD>& v, const Element& t1 )
{
 if(t1.Count < 0) {
  v.push_back(t1.Res_ID);
 }
 return v;
}

//for_each - cout << resid << endl
void display_resid ( const DWORD& ri )
{
 cout << ri << endl;
}

//벡터 테스트
 vector< Element > m_ElementList;

//요소를 추가한다.

 m_ElementList.push_back(Element(100, 100, 1, 2000));
 m_ElementList.push_back(Element(101, 100, 2, 2001));
 m_ElementList.push_back(Element(102, 100, 3, 2002));
 m_ElementList.push_back(Element(103, 100, -1, 2003));
 m_ElementList.push_back(Element(104, 100, 0, 2004));
 m_ElementList.push_back(Element(105, 100, -2, 2005));
 m_ElementList.push_back(Element(106, 100, -3, 2006));
 m_ElementList.push_back(Element(107, 100, -1, 2007));
 m_ElementList.push_back(Element(108, 100, 2, 2008));
 m_ElementList.push_back(Element(109, 100, 3, 2009));
 m_ElementList.push_back(Element(110, 100, 6, 2010));

//음수인 요소의 개수의 총 합을 구한다.

 int count = accumulate(m_ElementList.begin(), m_ElementList.end(), 0, count_minus_element_sum);

//음수인 요소의 가격의 총 합을 구한다.
 int price = accumulate(m_ElementList.begin(), m_ElementList.end(), 0, count_minus_element_price_sum);

//음수인 요소의 Res_ID의 목록을 구한다.
 vector<DWORD> m_ResID; //목록을 담을 배열을 선언한다.
 m_ResID.clear(); //클리어
 m_ResID = accumulate(m_ElementList.begin(), m_ElementList.end(), m_ResID, count_minus_resid);

//담겨진 요소의 Res_ID를 화면에 출력해 본다.

 for_each(m_ResID.begin(), m_ResID.end(), display_resid);

위와 같이 accumulator를 잘만 사용하면 아주 다양한 효과를 볼 수 있을거 같다.
총 합을 구하거나 모든 요소의 특징을 살펴 본다거나 하는 형태의 작업에 아주 탁월하다.

for_each는 for문을 사용하는 번거로움을 조금 해소해 줄수 있다.

Posted by gsi
: