2012-11-30 1 views
1

임시 배열로 요소를 이동하고 다시 복사하지 않고 C에서 배열의 하위 집합을 정렬하는 방법을 찾고있었습니다. 나는 qsort가에 대한 잘못된 이해를해야 할 수도 있습니다,하지만 난 아래의 코드가 작동해야한다고 생각 :배열의 부분 집합에서 qsort 호출

qsort(&my_struct_arr[1],3,sizeof(my_struct),my_struct_cmp); 
//my_struct_arr is a 4 element array, where i want to sort from position 1 to 3 
int my_struct_cmp(const void *a, const void *b) 
{ 
    my_struct A=*(my_struct*)a, B=*(my_struct*)b; 
    if(A.x-B.x < 0.01) return A.y-B.y; 
    return A.x-B.x; 
} 
typedef struct foo 
{ 
    float x, y; 
} my_struct; 

문제는, 그것이 작동하지 않습니다.

업데이트 1 : 좋아요, 문제에 대해 완전히 명확하지 않았습니다. 배열을 위치 1에서 3으로 초기화 했으므로 다음과 같은 요소가있는 배열이 있습니다.

{{ValueFromPreviousIteration.x, ValueFromPreviousIteration.y}, {x2, y2}, {x3, y3}}

내 문제는 위의 qsort는 전체 배열을 정렬하는 반면, 마지막 3 개 요소 만 정렬하려고한다는 것입니다.

+0

. 지금까지 게시 한 내용의'qsort()'호출은 원하는 것을 수행해야하는 것처럼 보입니다. (비교 함수는 몇 가지 해답에 설명 된 문제가 있지만). 문제가 비교가 아니라면, 당신이 우리에게 보여주지 않은 것일 것입니다. –

답변

0

int my_struct_cmp int를 반환합니다.

그리고 float을 반환합니다. 자동으로 int로 변환되며 아마도 0이됩니다.

그것이 작동하지 않는 이유입니다.

0

if(A.x-B.x < 0.01)이 맞습니까? if(A.x-B.x < 0.0)을 원할 수도 있습니다. 0.01 대신 0.0을 사용하십시오.

+0

나는 이것을 OpenGL 프로그램에서하고 있는데, x와 y는 좌표를 나타낸다. 화면에서 x의 0.01 차이는 실제 차이를 만들지 않습니다. – VSZM

1

비교 기능이 안정적이지 않습니다. 구조체가 전달되는 순서에 따라 다른 결과를 반환 할 수 있습니다.

구조체는 다음의 값을 고려

my_struct m = { -3.021, 30 }; 
my_struct n = { 3.010, 0 };  

int main(void) 
{ 
    int comp1 = my_struct_cmp(&m, &n); 
    int comp2 = my_struct_cmp(&n, &m); 

    printf("%d %d\n", comp1, comp2); 

    return 0; 
} 

제 1 비교가 m > n 나타내고, 두 번째 n > m 것을 나타내고있다. 이러한 종류의 동작은 qsort()을 혼란스럽게합니다.

+0

그래서'fabs()'에 대한 호출이 빠져 있습니다. ** 또한, ** 절대 값이 1보다 작 으면'+/- 1 '대신에 0을 잘못 반환합니다. –

0

난 당신이

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b; 
    return fabs(A.x - B.x) >= 0.01 ? (A.x > B.x) - (A.x < B.x) : (A.y > B.y) - (A.y < B.y); 
} 

또는 (그래서 휴대용되지 않음), 그렇지 않으면

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct A = *(my_struct*)a, B = *(my_struct*)b; 
    return fabs(A.x - B.x) >= 0.01 ? copysign(1, A.x - B.x) : copysign(1, A.y - B.y); 
} 

처럼 뭔가에 비교 기능을 수정할 필요가 있다고 생각하는의 기호를 결정하기위한 많은 플랫폼 별 솔루션이 존재 비교를하지 않고 떠 다니는 것은 사소한 문제는 아니지만 실제로는.

그리고 이것은 조금 더 빨리해야한다 : 당신은 훨씬 더 명확 문제를 보여주는 작은, 완전한, 컴파일 가능한 예제를 게시하여 문제를 만들 수 있습니다

int my_struct_cmp(const void* a, const void* b) 
{ 
    const my_struct *A = (my_struct*)a, *B = (my_struct*)b; 
    return fabs(A->x - B->x) >= 0.01 ? (A->x > B->x) - (A->x < B->x) : (A->y > B->y) - (A->y < B->y); 
}