본문 바로가기

Programing/C/C++

[list:sort] list:sort() 사용하기


목차




1 Introduction
2 Signature
3 Usage 1: sort()
4 Usage 2: sort(Compare comp)
5 Usage 3: sort(greater<T> pr)
6 References



1 Introduction #


list::sort는 list 내에 있는 element 들을 소팅 해준다. 소팅의 기준은 elements의 operator< 연산자 재 정의를 따르거나 sort에 전달되는 Compare에 따른다. 그래서 아래 Signatrue와 같이 두 가지 방식이 제공된다. Template과 재정의를 막각하게 제공해주는 STL의 성격을 잘 드러내 주는 api라고 볼 수 있다.




2 Signature #


두 가지 형식이 있으며
// type1. element의 operator< 연산자에 따라 소팅
void sort ( );

// type2. 전달되는 comp에 따라 소팅
template <class Compare>
void sort ( Compare comp );
//


주의 할 것은 VC6.0의 경우는 두 번째 방식에 대해서 표준을 따르지 않고 typ2를 아래와 같이 정의하고 있다.


// type1. element의 operator< 연산자에 따라 소팅
void sort();

// type2. struct std::greater<T>를 구현해서
// 넘겨줘야 한다.usage 3 참고
template<class Pred>
void sort(greater<T> pr);
//





3 Usage 1: sort() #


MyData라는 class는 id (int)와 name (std::string)을 가지고 있다고 가정해 보자 id에 따라 오름 차순 (작은 수가 앞으로 오게) 으로 오게 소팅을 하고 출력하는 코드는 void sort()를 이용해서 다음과 같이 작성할 수 있을 것이다.

list::sort를 위해서 MyData의 opeartor<을 재 정의 했다.


#include <list>
#include <string>
#include <iostream>

class MyData
{
// 편의상 public으로
public:
int m_nId;
std::string m_strName;

public:

// operator< 재 정의 sort에서 사용 됨
bool operator<(const MyData& other)
{
if( m_nId < other.m_nId)
return true;
else
return false;
};

// constructor
MyData(int nId, std::string strName)
{
m_nId = nId;
m_strName = strName;
};
};

void main()
{
std::list<MyData> dataList;

// elements 채우기
dataList.push_back( MyData(100, “alones1″));
dataList.push_back( MyData(50, “alones2″));
dataList.push_back( MyData(16, “alones3″));
dataList.push_back( MyData(58, “alones4″));

// 소팅: MyData::operator< 을 이용
dataList.sort();

std::list<MyData>::iterator it = dataList.begin();

// 결과 출력 id에 따라 오름 차순으로 정렬
while( it != dataList.end())
{
std::cout<<“id: “<<(*it).m_nId
<<” name: “<<(*it).m_strName<<std::endl;

++it;
}
}
//




4 Usage 2: sort(Compare comp) #


위의 MyData를 두 번째 sort()을 이용해서 정렬 해보자. 즉, 정렬 시 MyData의 operator<을 사용하지 않고 comp를 별도로 만들어서 정렬하는 것이다. comp는 두 개의 파라미터를 받으며 (물론 list의 element와 같은 type이어야 할 것이다) 소팅 시 첫 번째 파라미터가 두 번째 파라미터에 오면 true를 그렇지 않으면 false를 반환하게 작성하면 된다.

아래 Comp()는 Usage 1과 같은 결과를 가져오기 위해 작성되었다.


#include <list>
#include <string>
#include <iostream>

class MyData
{
// 편의상 public으로
public:
int m_nId;
std::string m_strName;

public:

// operator< 재 정의 sort에서 사용 됨
bool operator<(const MyData& other)
{
if( m_nId < other.m_nId)
return true;
else
return false;
};

// constructor
MyData(int nId, std::string strName)
{
m_nId = nId;
m_strName = strName;
};

MyData(){};
};

bool Comp(MyData first, MyData second)
{
if( first.m_nId < second.m_nId)
return true;
else
return false;
}

void main()
{
std::list<MyData> dataList;

// elements 채우기
dataList.push_back( MyData(100, “alones1″));
dataList.push_back( MyData(50, “alones2″));
dataList.push_back( MyData(16, “alones3″));
dataList.push_back( MyData(58, “alones4″));

// 소팅 (Comp를 사용했다)
dataList.sort(Comp);

std::list<MyData>::iterator it = dataList.begin();

// 결과 출력 id에 따라 오름 차순으로 정렬
while( it != dataList.end())
{
std::cout<<“id: “<<(*it).m_nId
<<” name: “<<(*it).m_strName<<std::endl;

++it;
}
}
//


※ 위 코드는 VC6.0에서 컴파일 되지 않는다. 앞에서도 거론했듯이 표준을 따르지 않고 두 번째 방식을 std::greater를 사용하기 때문이다.




5 Usage 3: sort(greater<T> pr) #


Usage1과 Usage2와 같은 결과를 내기 위해 VC6.0 에서는 아래 코드와 같이 struct greater<MyData>를 구현해서 넘겨줘야 한다.


#include <list>
#include <string>
#include <iostream>

class MyData
{
// 편의상 public으로
public:
int m_nId;
std::string m_strName;

public:

// operator< 재 정의 sort에서 사용 됨
bool operator<(const MyData& other)
{
if( m_nId < other.m_nId)
return true;
else
return false;
};

// constructor
MyData(int nId, std::string strName)
{
m_nId = nId;
m_strName = strName;
};

MyData(){};
};

// VC6.0에서는 greater를 구현
struct std::greater<class MyData>
{
bool operator()(const MyData& first, const MyData& second)
{
return first.m_nId < second.m_nId;
}
};

void main()
{
std::list<MyData> dataList;

// elements 채우기
dataList.push_back( MyData(100, “alones1″));
dataList.push_back( MyData(50, “alones2″));
dataList.push_back( MyData(16, “alones3″));
dataList.push_back( MyData(58, “alones4″));

// 소팅 (std::greater 사용)
std::greater<MyData> a;
dataList.sort(a);

std::list<MyData>::iterator it = dataList.begin();

// 결과 출력 id에 따라 오름 차순으로 정렬
while( it != dataList.end())
{
std::cout<<“id: “<<(*it).m_nId
<<” name: “<<(*it).m_strName<<std::endl;

++it;
}
}
//