Guest User

Untitled

a guest
Jun 12th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* a - source array;
  2.  * b - destination array;
  3.  * c - user supplied storage for counting, if not NULL;
  4.  * n - array size;
  5.  * r - range of values key values;
  6.  * k - key extractor.
  7.  */
  8. #define rsort_macro(a,b,c,n,r,k) {      \
  9.     int _t[r],                          \
  10.         *_c = (c) ? (c) : _t;           \
  11.     memset(_c, 0, sizeof(_t));          \
  12.                                         \
  13.     for (int _i = 0; _i < (n); ++_i) {  \
  14.         ++_c[k((a)[_i])];               \
  15.     for (int _i = 1; _i < (r); ++_i) {  \
  16.         _c[_i] += _c[_i-1];             \
  17.     for (int _i = n-1; _i >= 0; --_i) { \
  18.         (b)[--_c[k((a)[_i])]] = (a)[_i];\
  19. }
  20. #define bits(x,b_,_b) (*(unsigned long long *)&(x) >> (b_) & ((1 << (_b)) - 1))
  21. #define swap(a,b) { typeof(a) _t = a; a = b; b = _t; }
  22.  
  23. /* count sort by least significant byte 0..7,
  24.  * then by 8..15 and so on...
  25.  */
  26. void rsort_int(int *arr, int num)
  27. {
  28.     int *arr_ = malloc(num * sizeof(int));
  29.  
  30.     for (int shr = 0; shr < sizeof(int) * 8; shr += 8) {
  31.         #define key(x) bits(x,shr,8)
  32.         rsort_macro(arr, arr_, NULL, num, 0x100, key);
  33.         #undef key
  34.         swap(arr, arr_);
  35.     }
  36.  
  37.     free(arr_);
  38. }
  39.  
  40. /* radix sorting of double precision floating point numbers:
  41.  * 1. by mantissa, just like integers;
  42.  * 2. by exponent, just like integers;
  43.  * (1.111... * 2^n < 1.000... * 2^(n+1))
  44.  * 3. when sorted by absolute value, collect in reverse order,
  45.  *    stack negative ones on the left side
  46.  *    (descending by absolute value == ascending by signed value),
  47.  *    and positive ones on the right side
  48.  *    (descending-descending == ascending).
  49.  */
  50. void rsort_dbl(double *arr, int num)
  51. {
  52.     double *arr_ = malloc(num * sizeof(double));
  53.  
  54.     for (int shr = 0; shr < 52; shr += 13) {
  55.         #define key(x) bits(x,shr,13)
  56.         rsort_macro(arr, arr_, NULL, num, 0x2000, key);
  57.         #undef key
  58.         swap(arr, arr_);
  59.     }
  60.     #define key(x) bits(x,52,11)
  61.     rsort_macro(arr, arr_, NULL, num, 0x800, key);
  62.     #undef key
  63.     swap(arr, arr_);
  64.  
  65.     for (int i = num-1, i_ = 0, _i = num-1; i >= 0; --i) {
  66.         if (arr[i] < 0) arr_[i_++] = arr[i];
  67.                    else arr_[_i--] = arr[i];
  68.     }
  69.     swap(arr, arr_);
  70.  
  71.     free(arr_);
  72. }
  73.  
  74. /* sorting of strings:
  75.  * 1. find maxlen
  76.  * 2. sort by len
  77.  * 3. sort trailing subarray of ones not shorter than maxlen
  78.  *    by maxlen-1st letter
  79.  * 4. sort trailing subarray of ones not shorter than maxlen-1
  80.  *    by maxlen-2nd letter
  81.  * 5. ...
  82.  * 6. by 0th letter
  83.  */
  84. void rsort_str(unsigned char **arr, int num)
  85. {
  86.     // avoid computing same strlen twice
  87.     struct str {
  88.         unsigned char *ptr;
  89.         size_t         len;
  90.     } *arr_  = malloc(num * sizeof(struct str)),
  91.       *arr__ = malloc(num * sizeof(struct str));
  92.  
  93.     int maxl = 0;
  94.     for (int i = 0; i < num; ++i) {
  95.         arr_[i].ptr = arr[i];
  96.         arr_[i].len = strlen(arr[i]);
  97.         if (maxl < arr_[i].len)
  98.             maxl = arr_[i].len;
  99.     }
  100.  
  101.     /* for l=0..maxl: lidx[l] will become the index of the first string not
  102.      * shorter than l, when used for counting. Passing decremented pointer
  103.      * would do the trick, if there was guarantee, that no zero-length strings
  104.      * occur.
  105.      */
  106.     int lidx[maxl+1];
  107.     #define key(x) ((x).len)
  108.     rsort_macro(arr_, arr__, lidx, num, maxl+1, key);
  109.     #undef key
  110.     swap(arr_, arr__);
  111.  
  112.     for (int l = maxl, i = l-1; l > 0; --l, --i) {
  113.         memcpy(arr__, arr_, lidx[l] * sizeof(struct str));
  114.         #define key(x) ((x).ptr[i])
  115.         rsort_macro(&arr_[lidx[l]], &arr__[lidx[l]], NULL,
  116.                     num - lidx[l], 0x100, key);
  117.         #undef key
  118.         swap(arr_, arr__);
  119.     }
  120.  
  121.     for (int i = 0; i < num; ++i) {
  122.         arr[i] = arr_[i].ptr;
  123.     }
  124.     free(arr__);
  125.     free(arr_);
  126. }
Add Comment
Please, Sign In to add comment