【问题标题】:Sorting an array of double in C在C中对双精度数组进行排序
【发布时间】:2016-08-24 18:01:27
【问题描述】:

我正在尝试在 C 中对 double 类型的数组进行排序,但没有得到预期的输出。它似乎是对内存地址而不是实际值进行排序。我尝试将变量更改为 (*grade[i]) 但随后出现“一元 * 的无效类型参数”错误。这是有问题的代码片段。

void sortGrade(double grade[], int n){
int i, j, swapped;
double temp;
for (i = 0; i < n; ++i)
{
    for (j = i + 1; j < n; ++j)
    {
        if (grade[i] < grade[j])
        {
            temp = grade[i];
            grade[i] = grade[j];
            grade[j] = temp;
        }//end if
    }//end inner for
}//end outer for
printf("After sort:\nGrade\n");
for (i = 0; i < n; ++i)
{
    printf("%d\n", grade[i]);
}//end for
}//end sortGrade

任何帮助将不胜感激。 完全公开,这是给学校的,但是作业已经提交了,现在我只是想弄清楚如何让它真正发挥作用。

【问题讨论】:

  • 你的排序算法没问题。打印时出现错误:使用%f%g 打印浮点数。
  • 很难说如果你不告诉我们预期的输出是什么。显然,您应该在编译器中打开警告,因此不需要 M Oehms 建议。修复后,它将被排序,但可能不是您期望的方式。
  • 如果你对内存地址进行排序,那么显然项目的顺序不会改变。数组元素总是按内存地址排序。
  • M Oehm - 就是这样。现在一切正常。哇,我觉得自己像个白痴……谢谢你的帮助!
  • 周末不要觉得自己像个白痴,但下次一定要激活警告。 :)

标签: c arrays sorting pointers


【解决方案1】:

正如@M Oehm 已经提到的,在打印双精度值时,您必须使用%f 而不是%g。所以做

printf("%f\n", grade[i]);

而不是

printf("%d\n", grade[i]);

我假设目标是手动编写排序算法。如果没有,您可能想看看 stdlib 提供的 qsort。此函数执行快速排序排序算法。

// qsort(array pointer, number of elements, size of one element, compare function);
qsort(grade, n, sizeof(double), compare);

为了比较元素,您还需要一个比较函数。

// the compare function for double values
static int compare (const void * a, const void * b)
{
  if (*(double*)a > *(double*)b) return 1;
  else if (*(double*)a < *(double*)b) return -1;
  else return 0;  
}

【讨论】:

    【解决方案2】:

    在处理floatdouble 时必须小心。它们不是 100% 精确的。当处理看起来相同但较小位不同的数字时,您的排序算法会中断,因为浮点数只是实数的近似值。

    如果要比较两个 double 变量,请使用它。

    int areDoubleEqual(double a, double b) {
      if (fabs(a - b) <= 1000 * DBL_EPSILON * fabs(a + b)) {
          /*A and B are equal*/
          return 1;
      }
      return 0;
    }
    

    如果你想实现排序,我推荐使用 qsort。这是一个快速的例子

    #include <stdio.h>
    #include <float.h>
    #include <math.h>
    
    int areDoubleEqual(double a, double b) {
        if (fabs(a - b) <= 1000 * DBL_EPSILON * fabs(a + b)) {
            /*A and B are equal*/
            return 1;
        }
        return 0;
    }
    /*This will sort in descending order. If you want ascending order, interchange 1 and -1*/
    int compareDoubles(const void *a, const void *b) {
        double doubleA = *(double *) a;
        double doubleB = *(double *) b;
        if(areDoubleEqual(doubleA, doubleB)) {
            /*When A and B are equal, quick sort expects 0.
            For further details check documentation*/
            return 0;
        }
        /*A is bigger*/
        if((doubleA - doubleB) >
            ((fabs(doubleA) < fabs(doubleB) ? fabs(doubleB) :
            fabs(doubleA)) * DBL_EPSILON * 1000)) {
            return -1;
        }
        /*B is bigger*/
        return 1;
    }
    
    int main(void) {
    
        double doubles[5] = {4.3, 2.1, 10.564, 350332.323, 0.3};
        qsort(doubles, 5, sizeof(double), compareDoubles);
        for(int i = 0; i < 5; i++) {
            printf("%f ", doubles[i]);
        }
        printf("\n");
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      这应该可行:

         int i, j, swapped;
          double temp;
          for (i = 0; i < n; ++i)
          {
              for (j = i + 1; j < n; ++j)
              {
                  if (grade[i] < grade[j])
                  {
                      temp = grade[i];
                      grade[i] = grade[j];
                      grade[j] = temp;
                  }//end if
              }//end inner for
          }//end outer for
          printf("After sort:\nGrade\n");
          for (i = 0; i < n; ++i)
          {
              printf("%f\n", grade[i]);
          }//end for
          }//end sortGrade
      

      算法有效。唯一的错误是 printf:

      printf("%f\n", grade[i]); //for double values
      

      或更好

      printf("%lf\n", grade[i]); //for double values
      

      【讨论】:

        猜你喜欢
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-09
        • 1970-01-01
        • 2017-08-01
        • 2012-11-06
        相关资源
        最近更新 更多