2차원 배열 string 정렬하기

종강도 했겠다!
코드 질문 및 사연 하나(?) 올려봅니다!
결론만 읽고 싶으시면 마지막 문단으로 내려주세요~

프로젝트를 하다보니 클래스 내 public에 속한 string 2차원 배열을 특정 행을 기준으로 열정렬할 일이 생겼습니다.
변수 이름은 data이고 Class A(예시)의 public에 vector<vector> 로 정의되어 있습니다.
2차원 배열은 대략 아래 처럼 생겼고요.

name1 number3 price3 asdf1 qwer2
name3 number2 price1 asdf2 qwer1
name2 number1 price2 asdf3 qwer3

name을 기준으로 정렬하면,
name1 number3 price3 asdf1 qwer2
name2 number1 price2 asdf3 qwer3
name3 number2 price1 asdf2 qwer1

number를 기준으로 정렬하면,
name2 number1 price2 asdf3 qwer3
name3 number2 price1 asdf2 qwer1
name1 number3 price3 asdf1 qwer2

그래서 c++ algorithm 헤더의 sort 내장함수를 이용해서 정렬하려니 private member function 에러가 잔뜩… 떠서 구글에 나오는대로 여러가지 방법을 써봤는데 에러가 지워지지 않더라고요. static 선언을 사용해 보라던데 그걸로도 잘 해결되지 않았고요.

그래서 malloc 동적할당으로 string을 char *로 바꿔 qsort를 쓰려니 이건 또 동적배열이라 제대로 작동되지 않았고요.
(지금와서 생각해보니 열 전체를 char *로 만들고 \0를 잘 넣어줬다면 잘 작동했을 것 같습니다. 그땐 제출이 바빠서 고민해서 잘 구현할 시간에 어떻게든 돌아가게 만들어서 아래처럼 끝냈지만요.)

아무튼 구현은 아래처럼 해서 제출하고 대충 좋은 점수를 받았습니다.
프로젝트를 하면서 완성된 프로그램 하나를 만드는 게 목표였던 과제라 엣지 케이스를 넣거나 하진 않았거든요…

아래 코드는 g++ 7.4.0 환경에서 컴파일 되었습니다.

// data는 Class A(예시)의 public에 vector<vector<string>>으로 선언됨.
char tmpdata[200][6][30]; // 200개의 열, 6개의 행을 가진 길이 30의 문자열 배열 선언
int high = static_cast<int>(data.size()); // data.size()는 열의 개수를 반환

for(int a=0; a<high; ++a){
	for(int b=0; b<6; ++b){
		strcpy(tmpdata[a][b], data[a][b].c_str()); // cstyle로 변환
	}
}

qsort(tmpdata, high, 180, cmp);

for(int a=0; a<high; ++a){
	for(int b=0; b<6; ++b){
		data[a][b]=tmpdata[a][b]; // 정렬된 문자열을 string에 대입
	}
}

//sort(data.begin(), data.end(), cmp);
int cmp(const void *a, const void *b){
	char *A=(char *)a;
	char *B=(char *)b;
	return atoi(A+30)-atoi(B+30);
}

아무튼, 사연은 이정도고요.
질문은 이겁니다.
클래스 내 private에 속한 string 2차원 배열을 algorithm 헤더의 qsort가 아닌 sort를 사용해 c++스럽게 특정 행으로 기준으로 열정렬을 하고싶습니다.
물론 제가 직접 정렬을 구현해도 되지만, 이왕이면 STL의 sort를 이용해보고 싶습니다.
방법이 없을까요…?

1 Like

std::vector를 쓰시면 됩니다
C++스럽게 코딩한다는 것은 C 스타일 배열을 쓰지 않는다는 것을 의미하죠

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    vector<vector<string>> vs2dim {{"a", "b", "c"}, {"x"}, {"a", "aa"}};
    sort(vs2dim.begin(), vs2dim.end());
    for (const auto& row : vs2dim) {
        for (const auto& elem : row) {
            cout << elem << ' ';
        }
        cout << '\n';
    }   
}
1 Like

왜냐면 random access iterator여야 하거든요 ㅎㅎㅎ

제가 질문을 똑바로 못 드린 것 같습니다. 죄송합니다.
저렇게 정렬하면 1번째 행 대로 정렬, 2번째 행 대로 정렬, 이런 식으로 해서 끝번째 행까지 체크하여 정렬하게 되는데, 의도하려는 건 특정 행을 기준으로 열정렬을 하는 것이었습니다.
글의 설명과 예시를 보다 자세하게 수정하겠습니다.
번거롭게 해드려서 죄송합니다.

행을 기준으로 열을 정렬해요?? 흠… 열에 무엇을 보고 정렬하나요?

가로 string 값들이 하나의 struct 같은 느낌이라… 뭉쳐다녀야 하는 정보입니다.
그냥 struct로 묶어서 sort하는 게 가장 간단하려나요.

대충 이런 식입니다.
홍길동 010-0000-0000 서울
김개똥 010-1234-5678 대구

그러니까 그 값들중에 무엇을 보고 비교하는지가 궁금한거죵

열이 한번에 이동되야한다면 열 전체를 컨네이너에 넣어야할겁니다.