gpt4 book ai didi

c - 如何对包含 NaN 的 C 数组进行排序

转载 作者:行者123 更新时间:2023-11-30 20:18:05 25 4
gpt4 key购买 nike

一直在尝试实现我的代码作为对包括 NaN 在内的所有整数进行排序的方法。然而,似乎找不到可以将 NaN 排序到我的程序中的函数。代码能够对包括无穷大在内的其他整数进行排序,但是,当输入 nan 时,程序会识别输入,但不会将其排序到列表的开头。任何帮助,将不胜感激。

#include <stdio.h>
#include <math.h>

int main()
{
float array[100], swap;
int c, d, n;

printf("Enter the size of array\n");
scanf("%d", &n);

printf("Enter %d integers\n", n);

for (c = 0; c < n; c++)
scanf("%f", &array[c]);

for (c = 0; c < (n - 1); c++)
{
for (d = 0; d < n - c - 1; d++)
{
if (array[d] > array[d + 1])
{
swap = array[d];
array[d] = array[d + 1];
array[d + 1] = swap;
}
}
}

printf("Sorted array in ascending order:\n");


for (c = 0; c < n; c++)
printf("%f\n", array[c]);

return 0;
}

最佳答案

请注意,根据 C 标准,两个 NaN 值永远不会相等,即使它们具有相同的位模式。如果您要使用 NaN 对数据进行排序,您需要:

  1. 决定 NaN 值应根据正确值排序的位置(通常选择是“负无穷大之前”或“正无穷大之后”)。
  2. 使用比简单的 a > b 更精细的测试比较。

您可以找到分散在 C11 标准周围的相关信息。例如:

您可能会安排创建一个函数(可能是 inline 函数,除非您要将它传递给像 qsort() 这样的函数)来比较相关类型的两个浮点值(看起来像您正在使用 float ),它使用 isnan()isnanf()分类宏来确定一个或两个值是否为 NaN。如果两个值都是 NaN,该函数可能会返回一个指示相等的值,但如果其中一个是 NaN,则返回值会将其放置在另一个值之前或之后,具体取决于您希望 NaN 出现的顺序,并且它将返回用于比较其他值(正常值、零、无穷大、次正常数)的适当值 - 常规值和无穷大仅需要常规比较运算符,除非您需要对负零与正零进行正确排序。

例如,编写一个与 qsort() 一起使用的函数(并且使用类型 double 而不是 float )会产生类似的结果,假设数字应按升序排序,并且 NaN 应该比任何其他值都小。该代码包括从标准输入读取数据、打印数据、排序并再次打印的测试代码。

#include <math.h>

/* Belongs in a header! */
extern int cmp_double(const void *v1, const void *v2);

/* Sort doubles, with NaNs coming first */
/* Switch return values -1 and +1 after testing n1, n2 to sort NaNs last */
int cmp_double(const void *v1, const void *v2)
{
double d1 = *(const double *)v1;
double d2 = *(const double *)v2;
int n1 = isnan(d1);
int n2 = isnan(d2);

if (n1 && n2)
return 0;
if (n1)
return -1;
if (n2)
return +1;
if (d1 < d2)
return -1;
if (d1 > d2)
return +1;
// The values are 'equal', but …
if (d1 != 0.0)
return 0;
// They're both zero, but they could have different signs
int s1 = signbit(d1);
int s2 = signbit(d2);
if (s1 != s2)
return (s1) ? -1 : +1;
return 0;
}

#include <stdio.h>
#include <stdlib.h>

static void dump_doubles(const char *tag, int num, double values[num])
{
printf("%s (%d):\n", tag, num);
int line_len = 0;
for (int i = 0; i < num; i++)
{
int n = printf(" %+12.4f", values[i]);
if (n <= 0)
break;
line_len += n;
if (line_len >= 60)
{
line_len = 0;
putchar('\n');
}
}
if (line_len > 0)
putchar('\n');
}

int main(void)
{
enum { NUM_VALUES = 50 };
double values[NUM_VALUES];

int i = 0;

for (i = 0; i < NUM_VALUES; i++)
{
if (scanf("%lf", &values[i]) != 1)
break;
}

dump_doubles("Before sort", i, values);
qsort(values, i, sizeof(values[0]), cmp_double);
dump_doubles("After sort", i, values);

return 0;
}

注意将 -0.0 排序在 +0.0 之前所需的测试!

考虑输入数据:

3023.421800 9033.902200 nan -9370.952500 3088.884900 6829.135400 0
-0.000000 -inf -5267.546800 -8784.373300 5663.944600 -9728.231300 inf
-inf -5373.038600 4282.941600 6245.734200 -5533.975400 nan 8445.713600
+inf -9108.960400 -3796.671200 nan -2363.851300 877.460400 9936.416900
-3480.867400

输出是:

Before sort (29):
+3023.4218 +9033.9022 nan -9370.9525 +3088.8849
+6829.1354 +0.0000 -0.0000 -inf -5267.5468
-8784.3733 +5663.9446 -9728.2313 +inf -inf
-5373.0386 +4282.9416 +6245.7342 -5533.9754 nan
+8445.7136 +inf -9108.9604 -3796.6712 nan
-2363.8513 +877.4604 +9936.4169 -3480.8674
After sort (29):
nan nan nan -inf -inf
-9728.2313 -9370.9525 -9108.9604 -8784.3733 -5533.9754
-5373.0386 -5267.5468 -3796.6712 -3480.8674 -2363.8513
-0.0000 +0.0000 +877.4604 +3023.4218 +3088.8849
+4282.9416 +5663.9446 +6245.7342 +6829.1354 +8445.7136
+9033.9022 +9936.4169 +inf +inf

关于c - 如何对包含 NaN 的 C 数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55151688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com