Cod sursa(job #331179)

Utilizator mika17Mihai Alex Ionescu mika17 Data 12 iulie 2009 23:02:03
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.53 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

/*
template <class T>
void afis(vector <T> &A) {
     
     for (unsigned i = 0; i < A.size(); ++i)
      cout<<A[i]<<' ';    
     system("pause");
}*/

#define RAD_BYTES 4
#define RAD_MAXB 256
inline int getByte(int x,int rad) { return x >> rad * 8 & 0xFF; }
inline int getByteS(int x,int rad) { int tmp = x >> rad * 8 & 0xFF; return tmp + (tmp < 0x80 ? 0x80 : -0x80); }
inline bool cond(int radix) { return radix == RAD_BYTES - 1; }


//#define getByte(x,rad) (x >> rad * 8 & RAD_MAXB - 1)

/*
inline int getByte(int x,int rad) {
       
       int tmp = x >> rad * 8 & 255;
       if(x > 0) tmp += 256;
       return tmp;
}
*/

/*
inline uint getByteS(int x,uint rad) {
       
       uint tmp = x >> rad * 8 & RAD_MAXB - 1;
       //acu tre sa inversez bitul de semn
       return tmp >= 0x80 ? tmp - 0x80 : tmp + 0x80;
       //return tmp;
}

//template <class TYPE>
uint (*condition(int radix))(int,uint)  {
     
     //return &getByte;
     return radix == RAD_BYTES - 1 ? &getByteS : &getByte;
     //return (radix & 3) == 3 ? &getByteS : &getByte;
}
*/

void count_sort(vector <int> &A, vector <int> &cnt, int le, int ri, int radix, int (*get)(int,int))
{
     vector <int> aux(ri - le + 1); 
     
     int i;
     for(i = le; i <= ri; ++i)
      //cnt[ cond(radix) ? getByteS(A[i], radix) : getByte(A[i], radix) ] ++;
      cnt[ get(A[i], radix) ] ++;
     for(i = 1; i <= RAD_MAXB; ++i)
      cnt [i] += cnt[i - 1];
      
     //vector<int> cnt2(cnt);
     for(i = ri; i >= le; --i)
      //aux[ cnt[ cond(radix) ? getByteS(A[i], radix) : getByte(A[i], radix) ]-- - 1 ] = A[i];
      aux [ cnt[ get(A[i], radix) ] -- - 1 ] = A[i];
     for(i = le; i <= ri; ++i) A[i] = aux[i-le]; 
}

//template <class TYPE>
void msd_radix_r(vector <int> &A, int le, int ri, int radix) {
    
    if(le < ri && radix >= 0) {
          
          vector<int> cnt(RAD_MAXB + 1,0); //fac pe octeti nu pe cifre
    
          //cout<< "radix: " << radix << "   " << le << " " <<ri << ":\n";
          
          count_sort(A,cnt,le,ri,radix, cond(radix) ? &getByteS : &getByte); //afis(cnt); afis(A);
          
          for(int i = 0; i < RAD_MAXB; ++i) {
                       
                       //msd_radix_r(A, le + (i - 1 >= 0 ? cnt[i - 1] : 0), le + cnt[i] - 1, radix - 1);
                       msd_radix_r(A, le + cnt[i] , le + cnt[i + 1] - 1, radix - 1);
          }
    }                     
}

void msd_radix(vector <int> &A) {
     /*
     vector<int> pos,neg;
     
     for(unsigned i = 0, N = A.size(); i < N; ++i)
      A[i] < 0 ? neg.push_back(A[i]) : pos . push_back(A[i]);
     
     A.clear();
     
     msd_radix_r(neg,0,neg.size() - 1,RAD_BYTES - 1);
     msd_radix_r(pos,0,pos.size() - 1,RAD_BYTES - 1);
     
     for(unsigned i = 0, n1 = neg.size(); i < n1; ++i) A.push_back(neg[i]);
     for(unsigned i = 0, n2 = pos.size(); i < n2 ;++i) A.push_back(pos[i]);
     */
     msd_radix_r(A,0,A.size() - 1,RAD_BYTES - 1);
}

int main() {
    
    ifstream fin("algsort.in");
    ofstream fout("algsort.out");
    
    vector <int> A;
    unsigned N;
    
    fin >> N; A.resize( N );
    
    for(unsigned i = 0; i < N; ++i) fin >> A[i];
    
    msd_radix(A);
    //for(int i = 0; i < 20; ++i) {int x = rand() & 255; fout<< x << ' ' << getByte(x,0) << endl; }
    //cout << getByte(-1,3);
    for(unsigned i = 0; i < N; ++i) fout << A[i] << ' '; 
    //system("pause");
    return 0;
}