寻找最准确的双数字排序

时间:2015-11-10 21:46:25

标签: c++ sorting floating-point

我需要对小浮点数进行排序。 当我使用 std :: sort()//算法库时, 我发现在数量非常小的情况下它是不准确的。 如何以最准确的方式对此数组进行排序? 编辑:我的朋友向我建议这些代码,我不理解他们,他们似乎不能正确地完成第二项的配对

bool is_smaller(pair<double,int> a, pair <double , int> b)
{
return (b.first - a.first) > 1e9;
}
sort(a.begin(), a.end(), is_smaller);

#include <bits/stdc++.h>
using namespace std;

int main()
{
    string s;
    cin >> s;
    vector <pair<double,int> > a;
    double x = 0, y = 1, k, d;

    for(int i = 0;i < s.size();i++)
    {
        k = (x + y)/2;
        d = abs(k - y);
        //printf("[%.3lf %0.3lf]  %.3lf %.3lf \n",x, y, k, d);
        a.push_back({k,i+1});
        if(s[i] == 'l')
            y = k, x = k - d;
        else
            y = k + d, x = k;
    }
    sort(a.begin(), a.end());
    for (int i =0;i < a.size();i++)
        printf("%d\n",a[i].second);


    return 0;
}

输入:rrlllrrrlrrlrrrlllrlrlrrrlllrllrrllrllrrlrlrrllllrlrrrrrrrrrrrrrrrrrrrrrrrrrllrr 代码的输出: 1 2 6 7 8 10 11 13 14 15 19 21 23 24 25 29 32 33 36 39 40 42 44 45 50 52 53 51 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 49 48 47 46 43 41 38 37 35 34 31 三十 28 27 26 22 20 18 17 16 12 9 五 4 3

预期产量: 1 2 6 7 8 10 11 13 14 15 19 21 23 24 25 29 32 33 36 39 40 42 44 45 50 52 53 54 55 57 61 63 64 65 67 69 72 74 76 77 79 80 83 84 85 87 89 93 94 99 100 98 97 96 95 92 91 90 88 86 82 81 78 75 73 71 70 68 66 62 60 59 58 56 51 49 48 47 46 43 41 38 37 35 34 31 三十 28 27 26 22 20 18 17 16 12 9 五 4 3 评论:错误答案第28个数字不同 - 预期:&#39; 54&#39;,发现:&#39; 51&#39;

2 个答案:

答案 0 :(得分:1)

浮点运算的精度有限,虽然这种精度很高,但仍然有限。但

你算法生成一系列数字K(i),其中 |K(i+1) - k(i)| = 2^(-i)

|差异|上面是几何序列,因此它呈指数下降。因此,在ì的某个值处,差异将变得非常小,以至于无法将其报告到浮点表示中。

我用完全相同的输入运行你的代码,但我也打印了索引的数字,我没有应用排序。我打印的数字最多为50位小数(%.50f,只是为了看!)。我观察到了什么?

位置i > 53的数字都相等(在double可以达到的精度范围内)。因此,索引在53以上的数字将以某种方式随机排序,因为它们是相等的。

答案 1 :(得分:0)

如果以足够的精度打印浮点数:

printf("%03d %.18f\n",a[i].second,a[i].first);

然后你会看到计算导致排名51到100的相同浮点值...