2012-12-17 3 views
0

정렬 벡터 나 동적으로 할당 된 배열의 예가 있지만 정적 배열과 관련하여 도움이되지 않습니다. error: cannot convert 'int*' to 'const int (*)[10]' in argument passing정적 다차원 배열을 사용자 지정 비교 함수로 정렬

I :

내가 같이 호출
bool compare(const int (*a)[10], const int (*b)[10]); 

,

std::sort(array, array + 10, compare); 

내가 컴파일 오류가,의 내가 배열

int array[10][10]; 

와 비교 기능이 있다고 가정 해 봅시다 정렬 기능에서 (void**) 배열을 캐스팅하는 여러 가지 방법을 시도했지만 그때 나는 segmen 잘못되었다. 내 문제는 배열을 함수 매개 변수로 사용하는 것입니다. 그러나이 std :: sort를 사용하는 방법을 알 수는 없습니다. 그렇지 않으면 필자 자신의 정렬 함수를 작성해야합니다.

+0

당신은 당신의 비교 함수는 두 개의 함수 포인터를 소요 깨닫는다 : 가장 쉬운 방법은 (여기서 유연한 외부 치수) std::array<T, N>가 사용하는 정적 크기의 배열을 정렬하려면? –

+0

cdecl 상태 : "int 배열 10에 대한 포인터로 선언"int, 크기 10의 배열에 대한 포인터입니다. –

+0

소스를 인용 할 수 있습니까? 10 int의 배열에 대한 포인터는 const int (* a) [10]이 아닌 const int * a [10]이어야합니다. –

답변

2

의 비교 함수는 T 또는 const T& 유형의 인수를 수신해야합니다. 이 경우 2 차원 배열이 있으므로 요소 유형은 1 차원 배열 int[10]입니다. 동등

bool compare(int a[10], int b[10]); 

나 : 포인터 1 차원 배열의 붕괴 이후, compare이 될 수

bool compare(int *a, int *b); 

이 당신이있어 오류를 수정하지만 코드는 여전히 작동하지 않습니다 std::sort이 필요 컨테이너 요소는 할당 가능 (또는 C++ 11에서 이동 가능)하지만 배열은 할당 할 수 없습니다.

대신 사람들이 제안한대로 std::vector<std::vector<int> >을 사용할 수 있습니다. 성능 문제에 대한 두려움은 잘못된 것입니다. 2 차원 배열을 정렬 할 수있는 경우에도 오랜 시간이 걸리는 1 차원 배열을 많이 복사해야합니다. 반면에, 벡터를 교환하는 것은 단순히 포인터를 교환하는 것만으로 더 빠릅니다. 일반적으로 성능을 먼저 테스트하지 않은 경우 성능에 대한 가정을해서는 안됩니다.

+0

정렬하는 동안 배열의 내용을 복사하는 것이 옳습니다. STL 컨테이너로 전환해야한다고 생각합니다. 나는 그가 당신과 똑같은 대답에 1 분 전에 대답했기 때문에 @ 디에 마르에 대한 답을 주어야한다고 생각합니다. 다시 한 번 감사드립니다! –

+0

@HalilKaskavalci : 벡터와 달리'std :: array's의 내용도 복사해야한다는 것을 알고 있습니까? 나는 다른 대답에 대한 당신의 의견 때문에 묻고 있습니다. BTW 그것은 이전에 실제로 내 대답 이었지만 문제가되지 않습니다 - 당신은 어떤 대답이 좋든 받아 들여야합니다 :) – interjay

+0

나는 그들이 벡터처럼 포인터로 작동 할 수 있다고 생각했습니다. 내 콘텐츠의 크기가 실행 중에 변경되지 않기 때문에 고정 크기 컨테이너에 중점을 둡니다. 그렇다면 벡터를 사용하는 것 외에는 선택의 여지가 없을 것이라고 생각합니다. 대답에 관해서, 나는 그것이 당신 대답이라는 것을 몰랐다. 그것에 대해 미안하다. 성능 문제를 지적한 이후로 지금 대답을 선택하려고합니다 :). 편집 : 왜'std :: array' 내용을 복사해야하는지 자세히 설명해 주시겠습니까? 그것이'std :: array , 10>이면 복사를 피할 수 있습니까? –

1

우리가 STL과 C++을 사용한다면 말하자면 현대적인 스타일로 쓰고 실제로 STL을 사용하십시오.

현대 C++ (11) 사용 문제에서 내 시도 : 합계에 그것은 각각의 하위 배열 합계를 누적 사용

#include <vector> 
#include <iostream> 
#include <algorithm> 

typedef std::vector<int> ArrayInt; 
typedef std::vector< std::vector<int> > ArrayData; 

bool compare(const ArrayInt& a, const ArrayInt& b) { 
    std::cout << &(a) << ' ' << &(b) << std::endl; 
    int sumA = std::accumulate(a.begin(), a.end(), 0); 
    int sumB = std::accumulate(b.begin(), b.end(), 0); 
    return sumA < sumB; 
} 

int main(int argc, char** argv) { 
    ArrayData array = { 
     {1,2,4,0,3,7,6,8,3,3}, 
     {13,2,4,0,3,7,6,8,3,3}, 
     {10,2,4,0,3,7,6,8,3,3}, 
     {1,2,4,0,3,7,6,8,3,3}, 
     {16,2,4,0,3,7,6,8,3,3}, 
     {1,2,400,0,3,7,6,8,3,3}, 
     {1,2,4,0,3,7,6,8,3,3}, 
     {120,2,4,0,3,7,6,8,3,3}, 
     {1,2,4,0,3,7,6,8,3,3}, 
     {1,2,4,0,3,7,6,8,3,3} 
    }; 
    std::sort(array.begin(), array.end(), compare); 
    for (auto row : array) { 
     for (int num : row) 
      std::cout << num << ' '; 
     std::cout << std::endl; 
    } 
} 

및 종류 ..이 같은 행 합계를 가지고 있기 때문에 매우 비효율적이다 여러 번 ..하지만 그냥 사용자 정의 비교 기능을 과시하는 것입니다.


는 연습으로, 나는 정렬하기 전에, 합산을 할 가능한 모든 코어에 걸쳐 합산 일부를 배포하는 비동기를 사용하여이 버전을 썼다. 나는 그것이 주제에서 조금 벗어나고있어 미안해. 나는 어떤 사람들은 여전히 ​​유용 희망 :

그것은 pthread와 라이브러리 또는 유사한 컴파일 할 필요가
#include <vector> 
#include <iostream> 
#include <algorithm> 
#include <future> 

typedef std::vector<int> IntRow; 
typedef std::pair<int, IntRow> DataRow; 
typedef std::vector<DataRow> DataTable; 

int main(int argc, char** argv) { 
    // Holds the sum of each row, plus the data itself 
    DataTable array = { 
     {0, {1,2,4,0,3,7,6,8,3,3}}, 
     {0, {13,2,4,0,3,7,6,8,3,3}}, 
     {0, {10,2,4,0,3,7,6,8,3,3}}, 
     {0, {1,2,4,0,3,7,6,8,3,3}}, 
     {0, {16,2,4,0,3,7,6,8,3,3}}, 
     {0, {1,2,400,0,3,7,6,8,3,3}}, 
     {0, {1,2,4,0,3,7,6,8,3,3}}, 
     {0, {120,2,4,0,3,7,6,8,3,3}}, 
     {0, {1,2,4,0,3,7,6,8,3,3}}, 
     {0, {1,2,4,0,3,7,6,8,3,3}} 
    }; 
    // Make use of multiple cores if it's efficient enough 
    // get the sum of each data row 
    std::vector<std::future<int>> sums(array.size()); 
    auto next = sums.begin(); 
    for (auto& row : array) 
     *next++ = std::async([](const IntRow& row) { return std::accumulate(row.begin(), row.end(), 0); }, row.second); 
    // Get the results 
    auto nextRow = array.begin(); 
    for (auto& sum: sums) 
     (*nextRow++).first = sum.get(); 
    // Sort it 
    std::sort(array.begin(), array.end(), 
       [](const DataRow& a, const DataRow& b) { return a.first < b.first; }); 
    // Print it 
    for (auto row : array) { 
     for (int num : row.second) 
      std::cout << num << ' '; 
     std::cout << std::endl; 
    } 
} 

: std::sort이 유형 T의 요소의 컨테이너에서 호출

g++ -O6 sort.cpp --std=c++11 -g -lpthread

+0

답변을 주셔서 감사합니다. 그러나 제 경우에는 성능이 더 중요합니다. 유전 알고리즘을 사용하고 결과를 얻기 위해 10-15 분 동안 프로그램을 실행합니다. 나는이 시간을 줄이기 위해 모든 것을해야한다. 크기 검사 때문에 속도가 느린 벡터를 동적으로 생성하면 실행 시간이 훨씬 길어집니다. 그래서 나는 구식 C 스타일처럼 작동하도록 despereatly하려고합니다. 앞에서 언급했듯이'const int * a [10]'함수 포인터에 대해서도 도움이되지 않았습니다. 정렬 기능에 오류가 있습니다. 다시 한 번 대답 해 주셔서 감사합니다. –

+0

위에서 정의한 compare 함수는 함수 포인터를 사용하지 않고 int [10]에 대한 포인터를 사용합니다. – interjay

+0

감사합니다 - 내 대답에서 그 줄을 제거했습니다 .. 두번 쳐다 보았어야합니다 :) – matiu

1

비교 함수는 전달 된 요소에 대한 반복자가 아니라 참조 된 반복자, 즉 값 유형을 가져옵니다.

bool compare(int (&a0)[10], int (&a1)[10]); 

당신은 당신이 실제로 배열 반복자로 호출 할 수 있음을 확인할 수 있습니다 : 따라서, 귀하의 비교 함수는 아래와 같이 선언 될 필요가

compare(*(std::begin(array) + 0), *(std::begin(array) + 1)); 

그러나, 이것은하지 않습니다 배열을 정렬 할 수 있습니다. 내장 배열은 복사 할 수 없습니다. 그렇지,

std::array<int, 10> array[10]; 
std::sort(std::begin(array), std::end(array)); 
+0

std :: array를 상기시켜 주셔서 감사합니다. 나는 지금 그것에 집중할 것이다. –