我正在嘗試qsort在 C的幫助下按降序對陣列進行排序。
#include<stdio.h>
#include<stdlib.h>
int compareFloat(const void* p1, const void* p2){
const float* pa = p1;
const float* pb = p2;
return pb - pa;
}
int main()
{
float arr[] = {1.5, 1.6, 1.38};
qsort(arr, 3, sizeof(float), compareFloat);
printf("%.2f %.2f %.2f", arr[0], arr[1], arr[2]);
return 0;
}
上面代碼的輸出是“1.60 1.38 1.50”,這是錯誤的;但是,當陣列初始化為float arr[] = {1.38, 1.6, 1.5}時,答案是正確的(即“1.6, 1.5, 1.38”)。
為什么?
uj5u.com熱心網友回復:
在比較功能中
int compareFloat(const void* p1, const void* p2){
const float* pa = p1;
const float* pb = p2;
return pb - pa;
}
您正在回傳兩個指標的差異。但是您需要比較指向的值而不是指標本身。
該功能可以如下所示
int compareFloat( const void* p1, const void* p2)
{
float a = *( const float * )p1;
float b = *( const float * )p2;
return ( a < b ) - ( b < a );
}
這是一個演示程式。
#include <stdio.h>
#include <stdlib.h>
int compareFloat( const void *p1, const void *p2 )
{
float a = *( const float * )p1;
float b = *( const float * )p2;
return ( a < b ) - ( b < a );
}
int main( void )
{
float arr[] = { 1.5, 1.6, 1.38 };
const size_t N = sizeof( arr ) / sizeof( *arr );
qsort( arr, N, sizeof( float ), compareFloat );
printf( "%.2f %.2f %.2f\n", arr[0], arr[1], arr[2] );
}
程式輸出為
1.60 1.50 1.38
uj5u.com熱心網友回復:
你的函式的回傳值compareFloat是錯誤的……有兩個原因。
首先,你減去的是指標,而不是它們指向的值——所以你需要*pb - *pa.
1.6但是,即使那樣,您的測驗對于像and這樣的值也會失敗1.5,因為減法的結果將是非零但小于一。因此,當轉換為int回傳型別時,函式將回傳0(表示值相同),即使它們不同。
您需要回傳至少兩次比較的結果:
int compareFloat(const void* p1, const void* p2)
{
const float* pa = p1;
const float* pb = p2;
return (*pa < *pb) - (*pa > *pb);
}
uj5u.com熱心網友回復:
您的比較例程不正確。
return pb - pa;
在這里,您要減去兩個指標值。
如果您使用的是整數,則改為減去指標指向的數字:
return *pb - *pa;
但是由于小數部分的截斷,這不適用于浮點數。您需要明確比較并回傳正確的值。
if (*pa > *pb) {
return -1;
} else if (*pa < *pb) {
return 1;
} else {
return 0;
}
uj5u.com熱心網友回復:
其他人很好地指出了兩個缺陷:
OP的指標減法應該是浮點FP減法/比較。
結果必須是
int.int compareFloat(const void* p1, const void* p2){ const float* pa = p1; const float* pb = p2; // return pb - pa; return (*pb > *pa) - (*pb < *pa); }
還有另一個問題:如果任一 FP 值可能是非數字NAN,則需要額外考慮以保持比較兼容。我們需要一種在引數反轉時回傳相反符號的排序。還有如果a > b和b > c,那么a > c。 (*pb > *pa) - (*pb < *pa)上面的 NAN 無法實作這一點。
int compareFloat(const void* p1, const void* p2){
const float f1 = *(const float *)p1;
const float f2 = *(const float *)p2;
if (isnan(f1)) {
if (isnan(f2)) {
// Since both are NA, just compare bit patterns
return memcmp(p1, p2, sizeof (float));
}
return 1; // Consider NAN < all non-NANs
}
if (isnan(f2)) {
return -1;
}
return (f2 > f1) - (f2 < f1);
}
int main() {
float arr[] = {1.5f, 1.6f, NAN, 1.38f}; // Better to use float constants
qsort(arr, 4, sizeof(float), compareFloat);
printf("%.2f %.2f %.2f %.2f", arr[0], arr[1], arr[2], arr[3]);
return 0;
}
輸出
1.60 1.50 1.38 nan
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/462153.html
下一篇:計劃的動態自定義過濾表
