stl 데이터 합치기
글쓴이: girneter / 작성시간: 금, 2005/06/17 - 12:03오후
class Some; class Compare; class SomeList { private: set<Some, Compare> infolist; public: ... } SomeList AAA;
위와 같이 STL set 을 member 로 갖는 class 가 있고
이 클래스 타입의 object AAA 가 있습니다
이제 매번
역시 SomeList 타입의 BBB 를 만들어
Some 데이터를 계속 추가하다가
모아놓은 그 데이터들을 AAA 에 쏟아붇고 (즉 추가하고)
BBB 는 해제하고,
다시 또 만들어서 추가하다가 AAA 에 쏟아부어서
AAA 에 계속 데이터가 쌓이게 됩니다.
이제 질문.
1. AAA 와 BBB 는 같은 클래스 타입이지만 infolist 는
private 으로 선언되어 있자나요.
BBB 에 있는 데이터들을 AAA 로 옮길때 어떻게 하는게
젤 바람직할까요?
쉽게 가자면 클래스에
set<>* getList() 함수를 만들어서
BBB 에서 set 꺼내고 이걸 AAA 의 set 에 추가해주면
되겠지만 private 데이터를 이렇게 밖으로 꺼내서
막 다뤄도 괜찮은건가요?
2. 제가 갖고 있는 STL 책에는
list 는 merge 함수를 제공하는데,
set 에는 없는것처럼 나와있습니다.
혹시 set 은 merge 함수가 없습니까?
그럼 두 set 을 합칠 때는 일반 알고리즘 merge 를 써야겠죠?
아니면 구조를 list 로 바꾸어서
매번 sort 시키고 merge 시키는게 더 나을까요?
Forums:
Re: stl 데이터 합치기
그냥 insert를 하면 제일 쉽겠는데요.
상황에 따라 달라지지만 일반적으로는 좋지 않습니다. 이런 물음을 하신다는 것 자체가
문제가 있음을 느끼고 있다는 뜻이므로 이유는 길게 말씀드리지 않아도 되겠죠.
set에는 merge가 필요 없습니다. set::insert로 같은 일을 효율적으로 할 수
있으니까요. 일반적으로 정렬된 컨테이너를 합치기 위해서 merge나 set_union
알고리즘을 쓸 수 있지만 합친 결과를 담아둘 임시 컨테이너를 마련해야 하고 합친
후에 다시 원하는 컨테이너로 복사해야 합니다.
일반 알고리즘보다 컨테이너의 멤버 함수를 쓰는 것이 좋은 이유는 멤버 함수는
컨테이너 클래스의 내부 구조를 잘 알고 있으므로 같은 일을 해도 더 효율적으로
할 수 있기 때문입니다. (적어도 일반 알고리즘보다 비효율적이지는 않습니다.)
번거롭지 않겠습니까? 성능의 저하도 예상되는군요.
아...set<>.insert(begin, end) 가 그
아...
set<>.insert(begin, end) 가 그렇게 쓰는거였구나
보고도 지나쳤습니다.
친절하고 명쾌한 답변 정말 고맙습니다.
내친김에 질문 하나 더 드릴께요.
object AAA 에서 BBB 의 private member 인
infolist 를 바로 접근할 수 있었던건
둘이 같은 클래스이기 때문이자나요
만약 다른 클래스인데 멤버로 같은 set<> 을 갖고
있는 경우였다면 어떻게 하나요?
할 수 없이 set<>* getList() 함수를 써야겠죠?
클래스 설계가 잘못되었으니 첨부터 다시 설계하든가.
혹은 friend 가 이럴때 사용하는거였던가?
개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?
글쎄요... 두 클래스의 목적이라든가 서로간의 관계에 대한 정보가 없어서
글쎄요... 두 클래스의 목적이라든가 서로간의 관계에 대한 정보가 없어서 대답하기
힘들군요. 정말 다양한 선택이 있을 수 있습니다.
딴 얘기지만 set을 합치는 것은 클래스의 구현에 관한 내용일 가능성이 높습니다.
구현 방법에 맞춰 인터페이스를 정하지 마시고 클래스가 충분히 추상화되었는지
거시적으로 생각해 보세요. Bjarne Stroustrup의 말을 인용합니다.
set 에는 set<>.insert(begin, end) 이런
set 에는 set<>.insert(begin, end) 이런 형식 없습니다.(두개의 iterator 파라미터)
집합의 더하기는 단순히 두 집합을 연결하는게 아니죠
(집합에 들어있는 원소는 유니크해야 하니깐요)
그래서 merge 를 사용 할 수 없습니다.
집합끼리는 합집합으로 하는거죠.
고로 set_union() 를 사용하세요. list merge 에 해당하는거죠
[quote="ssehoony"]set 에는 set<>.ins
set에 insert(begin,end) 가 없는 이유는,
"set에 들어갈 수 있는 key가 unique 해야 하기 때문에, insert하고자 하는 begin-end 사이에 이미 존재하는 키가 있을 경우에, 이를 추가할지 말지의 처리가 애매모호해서"
라고 보시는게 더 나을듯 합니다.
즉 정의될 수 없는 동작을 하려고 하기 때문이죠...
list에 있는 merge는 용도를 좀 알고 접근하셔야 할 듯 합니다.
merge라는 것이 두 list가 sort가 되어있다는 가정을 두고 있습니다.
listA.merge(listB)
이면 listC 는 listA와 listB가 하나로 합쳐지기는 하는것이지만,
listA와 listB가 sort되어 있다는 전제와 함께, 결과로 나오는 listA가 sort가 된 결과라는 전제가 깔리게 됩니다.
하지만, set은
1. 이러한 순차적인 데이터구조로만 정의되지는 않습니다.
(물론 std::set 의 begin -> end 가 순차적인 구조를 가지도록 유지할 수는 있기는 합니다만, 이는 std의 정의입니다.
set은 그냥 set으로 보시는게 맞을듯 합니다.)
2. 더구나, set에서 값들을 begin - end 를 보시면 아시겠지만 sort된 결과를 리턴하게 됩니다.
내부적으로 tree구조를 이용해서 (MFC의 set입니다. sgi 혹은 다른 std의 것은 어떻게 되어있는지는 모르겠습니다만..)
begin 부터 end 까지의 값들을 얻어내려 할 때에, 값들의 대소가 순서를 유지하도록 합니다.
물론, 이렇게 해야 값이 중복으로 들어가는 것을 피할 수 있겠지만요...
즉 set은 merge를 위한 선행조건과 목적을 만족할 수가 없고, 또한 만족 시킬 필요가 없기 때문에 존재하지 않는것입니다.
데이터를 순차적으로 가질 수 있고, 또한 순차적인 데이터를 sort할 수 있는 때, 순차적으로 sort된 두 데이터 집합의 merge의 결과는 두 집합을 합친 그리고 순차적인 데이터 구조를 유지하는 결과를 가진다.
헉 실수로 로그인을 안했군요.윗글 제가 작성했습니다.
헉 실수로 로그인을 안했군요.
윗글 제가 작성했습니다.
WOW Wow!!!
Computer Science is no more about computers than astronomy is about telescopes.
-- E. W. Dijkstra
[quote="Anonymous"][quote="ssehoony"]set
input iterator 2개를 받는 set::insert도 있습니다.
first와 last 범위를 순회하면서 이미 키가 존재한다면 추가하지 않고 넘어갑니다.
모호할 이유가 없지요.
set<>* getList() 대신 set<>::i
set<>* getList() 대신 set<>::iterator& getBeginOfList()와 getEndOfList()를 만드는건 어떨까요?
----------------------------
May the F/OSS be with you..
[quote="doldori"][quote="Anonymous"][quo
네 두개의 iterator 을 받는 insert 가 set 에도 있었군요.
제가 원글을 쓸때 레퍼런스를 확인하고 쓴 글이었는데, 그때 발견하지 못했는데 지금 다시 확인해 보니 있네요.
잘 못된 내용 올려서 죄송합니다.
댓글 달기