一直在尝试实现我的代码,以对包括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;
}
答案 0 :(得分:1)
请注意,根据C标准,即使两个NaN值具有相同的位模式,它们也不会比较相等。如果要使用NaN排序数据,则需要:
a > b
比较要精致得多的测试。您可以找到散布在C11标准周围的相关信息。例如:
<float.h>
isnan
macro signbit
macro fmax
functions 您可能会安排创建一个比较两个相关类型的浮点值的函数(可能是inline
函数,除非您要将其传递给类似qsort()
的函数)。似乎您正在使用float
或isnan()
分类宏来确定两个值中的一个或两个都是NaN的isnanf()
。如果两个值都是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
答案 1 :(得分:-1)
如评论中所述,您的代码是C代码而不是C ++。这是您的C ++代码,带有附加条件,可以解决您的问题:
#include <iostream>
#include <vector>
#include <cmath>
int main()
{
std::size_t array_size;
std::cout << "Enter the size of array\n";
std::cin >> array_size;
std::cout << "Enter " << array_size << " integers\n";
std::vector<float> array(array_size);
for(std::size_t i = 0; i < array.size(); ++i)
std::cin >> array[i];
for(std::size_t a = 0; a < array.size() - 1; ++a)
for(std::size_t b = 0; b < array.size() - 1 - a; ++b)
if(std::isnan(array[b + 1]) || array[b] > array[b + 1])
std::swap(array[b], array[b + 1]);
std::cout << "Sorted array in ascending order:\n";
for(const auto& a : array)
std::cout << a << '\n';
return 0;
}
如果您不想自己编写所有排序内容,则可以使用更多的C ++和算法库(以及添加的输入检查)来做到:
template<typename T>
T get_input()
{
T input;
while(true)
{
std::cin >> input;
if(std::cin)
return input;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cout << "Invalid input! Please try again.\n";
}
}
int main()
{
std::cout << "Enter the size of array\n";
std::size_t array_size = get_input<std::size_t>();
std::cout << "Enter " << array_size << " integers\n";
std::vector<float> input(array_size);
for(auto& a : input)
a = get_input<float>();
std::sort(input.begin(), input.end(), [](const auto& a, const auto& b){ return std::isnan(a) || a < b; });
std::cout << "Sorted array in ascending order:\n";
for(const auto& a : input)
std::cout << a << '\n';
}