sort big data

或许是巧合,sorting是我们队名,下午的题目也是sorting题目,但是我们当时做的并不好,个人觉得。

首先思路比较有限,没有开阔,尽管分治在理论上和直接sort似乎没有太多的差别

直接排序nlogn
分治排序(假设刚好整分) n/m log n/m m +n= n(1+logn/m)

正如胡瀚森大神所说,log 50W~=19 和log 5W +1~=17 差别几乎是可以忽略的, 所以用分支并不会带来较明显的性能优势,自己实践发现的确也是如此。

这里实现了几个版本

  1. 直接sort,快排,也是较快的

  2. unique可以调用系统的,不一定是unique_copy,或者自己写一个one-pass的,自己写了一个双while,后来发现其实是可以缩掉一个while,正如fawkes大神所说,他习惯判断是否和前一个元素
    相等,我的是和之前已经处理过的最后一个元素是否相等。

  3. 华师软院likexi同学组提到的分治我自己写了一下,结果发现了自己对于pop_heap api使用的一个严重错误。其实本不需要用heap,但是这样也好,多暴露一些问题。
    因为分别是按照极短排序直接append就可以了,不用merge。

pop_heap 我以为是: swap(a[0],a[size-1]), size—; Filterdown(0), 但是发现不是的,a[0]也要参与比较,这样我已开始a[0] 越界了调用pop_heap 就会出bug.

pop_heap 的 Preconditions 是三个条件,[first, last)至少一个元素,也即last>first, 并且[first, last] is a heap, 所以我的做法是错误的。因为first已经越界了。

所以我目前想到的做法就是 手动swap size— 然后make_heap。 群里某童鞋发给我STL源码,之前一直以为这种自己是接触不到的,现在也要逐渐开始懂源码了。

但是后来看了下,发现其实还是要照原来的思路来理解,遇到问题不是pop_heap的问题,而是MSVC那个蛋疼的STL,那个蛋疼的algorithm里面的pop_heap, 管他怎么实现,反正和SGI STL不一样就对了。但是SGI STL里面要求原始的[first, last)是heap,这里也有异或

  1. 如果直接merge 复杂度一般是比heap要高的。

附上搞的代码,不要用MSVC编译。。。。

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
typedef unsigned int ui;
const ui MAXNUM=5e5;

// 实现基本的,分支的,首先unique_copy, 计时,还有多线程,Java Bigint,处理不止10位的整数,string char*, bitset, bitmap, 位率
ui a[MAXNUM];
ui b[MAXNUM];
ui n;
ui bucket_num=32;
ui MAXUINT=0xFFFFFFFF;
clock_t start;
clock_t endc;
vector<ui> bucket[MAXNUM];
vector<ui> veca;

vector<pair<int,int> > bucketpos;
void removerepeated_fawks(vector<ui>& a)
{
    int save = 0;
    int n = a.size();
    for (int i = 0; i < n; i++)
    {
        if (!i || a[i] != a[i - 1]) a[save++] = a[i];
    }
    a.resize(save);
}
void removerepeated(vector<ui>& a)
{

    if(a.size()==0) return ;
    ui bucketn = a.size();
    ui i=1,curi=0;
    while(i<bucketn)
    {
        while(i<bucketn && a[i]==a[curi])
            i++;
        if(i==bucketn) break;
        a[++curi]=a[i++];
    }
    a.resize(curi+1);
}
void removerepeated_onewhile(vector<ui>& a)
{
    if(a.size()==0) return;
    ui i=1,curi=0;

    while(i<a.size())
    {
        if(a[curi]!=a[i])
        {
            a[++curi]=a[i++];
        }
        else
            i++;
    }
    a.resize(curi+1);
}
void sort_unique_copy()
{
    sort(a,a+n);
    //ui* end_b=unique_copy(a,a+n,b);
    ui* aend=unique(a,a+n);
    //printf("%d\n",end_b-b);
    printf("%d\n",aend-a);
    for(ui* i=a;i!=aend;i++)
        printf("%u\n",*i);

    /*
    for(size_t i=0;i<n;i++)
        printf("%d ",b[i]);
    */
    puts("");
}

void sort_one_pass()
{
    //start=clock();
    sort(veca.begin(),veca.end());
    //endc=clock();
    //printf("STL Sorting Time: %f\n",(double)(endc - start) / CLOCKS_PER_SEC);
    removerepeated_fawks(veca);
    /*
    ui i=1,curi=0;
    while(i<n)
    {
        while(i<n && a[i]==a[curi])
            i++;
        if(i==n) break;
        a[++curi]=a[i++];
    }*/
    //start=clock();
    printf("%d\n",veca.size());
    for(ui i=0;i<veca.size();i++)
        printf("%u\n",veca[i]);
    //endc=clock();
    //printf("Writing Time: %f\n",(double)(endc - start) / CLOCKS_PER_SEC);
}

bool AtLeastTwoArray()
{
    if(bucketpos.size()>=2)
        return true;
    else
        return false;
}

bool comp(const pair<int,int> i, const pair<int,int> j)
{
    return bucket[i.first][i.second]>bucket[j.first][j.second];
}

void sort_m_bucket_append()
{
    bucketpos.clear();
    //ui threshold[bucket_num];
    //for(ui i=0;i<bucket_num;i++)
    //    threshold[i]=n/4*i;
    //ui merge[n];
    for(ui i=0;i<bucket_num;i++)
        bucket[i].clear();
    ui bucket_cap=MAXUINT/bucket_num+1;
    for(ui i=0;i<n;i++)
    {
        bucket[veca[i]/bucket_cap].push_back(veca[i]);
    }

    for(ui i=0;i<bucket_num;i++)
    {
        sort(bucket[i].begin(),bucket[i].end());
        removerepeated(bucket[i]);
    }
    ui ai=0;
    for(ui i=0;i<bucket_num;i++)
    {
        for(ui j=0;j<bucket[i].size();j++)
            a[ai++]=bucket[i][j];
    }
    printf("%u\n",ai);
    for(ui i=0;i<ai;i++)
        printf("%u\n",a[i]);
}

void sort_m_bucket()
{
    bucketpos.clear();
    //ui threshold[bucket_num];
    //for(ui i=0;i<bucket_num;i++)
    //    threshold[i]=n/4*i;
    //ui merge[n];
    for(ui i=0;i<bucket_num;i++)
        bucket[i].clear();
    ui bucket_cap=MAXUINT/bucket_num+1;
    for(ui i=0;i<n;i++)
    {
        bucket[veca[i]/bucket_cap].push_back(veca[i]);
    }

    for(ui i=0;i<bucket_num;i++)
    {
        sort(bucket[i].begin(),bucket[i].end());
        removerepeated(bucket[i]);
    }

    //vector<ui> pos(bucket_num,0);
    for(ui i=0;i<bucket_num;i++)
    {
        if(bucket[i].size()>=1)
            bucketpos.push_back(make_pair(i,0));
    }
    make_heap(bucketpos.begin(),bucketpos.end(),comp);
    ui min,ai=0;
    ui mini;
    while(AtLeastTwoArray())
    {
        a[ai++]=bucket[bucketpos.front().first][bucketpos.front().second];



        bucketpos.front().second=bucketpos.front().second+1;
        if(bucketpos.front().second>=bucket[bucketpos.front().first].size())
        {
            pop_heap(bucketpos.begin(),bucketpos.end(),comp);
            bucketpos.pop_back();
        }
        else
        {
            pop_heap(bucketpos.begin(),bucketpos.end(),comp);
            push_heap(bucketpos.begin(),bucketpos.end(),comp);
        }

        /*
        if(bucketpos.front().second+1<bucket[bucketpos.front().first].size())
        {
            bucketpos.front().second=bucketpos.front().second+1;
            pop_heap(bucketpos.begin(),bucketpos.end(),comp);
            push_heap(bucketpos.begin(),bucketpos.end(),comp);
        }
        else
        {
            swap(bucketpos.front(),bucketpos.back());
            bucketpos.pop_back();
            make_heap(bucketpos.begin(),bucketpos.end(),comp);
        }
        */
        /*
        min=0xFFFFFFFF;
        for(ui i=0;i<bucket_num;i++)
        {
            if(pos[i]>=bucket[i].size())
                continue;
            if(min>bucket[i][pos[i]])
                min=bucket[i][pos[i]],mini=i;
        }
        a[ai++]=min;
        pos[mini]++;*/
    }
    if(bucketpos.size()==1)
    {
        for(ui j=bucketpos[0].second;j<bucket[bucketpos[0].first].size();j++)
            a[ai++]=bucket[bucketpos[0].first][j];
    }


    //merged ai number of type ui into a[]
    printf("%u\n",ai);
    for(ui i=0;i<ai;i++)
        printf("%u\n",a[i]);

    /*
    for(ui i=0;i<bucket_num;i++)
    {
        if(i!=0)
            sort(a+(n/bucket_num)*i+1,(n/bucket_num)*(i+1)+2)
        else
            sort(a,a+n/bucket_num+1);
    }*/

    //sort(a,a+n/bucket_num+1);
    //sort(a+n/bucket_num+1,a+n/bucket_num)
}

int main()
{
    freopen("in.txt","r",stdin);
    freopen("out_unique_copy.txt","w",stdout);

    /*
    srand(time(NULL));
    printf("%d\n",MAXNUM);
    for(ui i=0;i<MAXNUM;i++)
        printf("%u\n",ui((double)rand()/RAND_MAX * MAXUINT));
    */
    start=clock();
    scanf("%d", &n);
    ui x;
    for(ui i=0;i<n;i++)
        scanf("%u", &x),veca.push_back(x);
    endc=clock();
    printf("Reading Time: %f\n",(double)(endc - start)/CLOCKS_PER_SEC);
    start=clock();
    sort_m_bucket();
    endc=clock();
    printf("STL Sorting Time: %f\n",(double)(endc - start) / CLOCKS_PER_SEC);
    //duration = (double)(finish - start) / CLOCKS_PER_SEC
    //printf("Reading Time: %f\n",(double)(end - start) / CLOCKS_PER_SEC);

    return 0;
}

Posted by richard爱闹 - 9月 1 2014
如需转载,请注明: 本文来自 Richard