Chơi gôn + Sắp xếp nhanh trong C


11

[ Cập nhật mới nhất: chương trình điểm chuẩn và sơ yếu lý lịch có sẵn, xem bên dưới]

Vì vậy, tôi muốn kiểm tra sự đánh đổi tốc độ / độ phức tạp bằng một ứng dụng cổ điển: sắp xếp.

Viết hàm ANSI C sắp xếp một mảng các số dấu phẩy động theo thứ tự tăng dần .

Bạn không thể sử dụng bất kỳ thư viện, cuộc gọi hệ thống, đa luồng hoặc ASM nội tuyến.

Các mục được đánh giá dựa trên hai thành phần: chiều dài mã hiệu suất. Ghi điểm như sau: các mục nhập sẽ được sắp xếp theo độ dài (nhật ký của #char character không có khoảng trắng, do đó bạn có thể giữ một số định dạng) và theo hiệu suất (nhật ký của #seconds trên điểm chuẩn) và mỗi khoảng [tốt nhất, tệ nhất] được chuẩn hóa tuyến tính thành [ 0,1]. Tổng số điểm của một chương trình sẽ là trung bình của hai điểm số được chuẩn hóa. Điểm số thấp nhất chiến thắng. Một mục nhập cho mỗi người dùng.

Sắp xếp sẽ phải (cuối cùng) được đặt đúng chỗ (tức là mảng đầu vào sẽ phải chứa các giá trị được sắp xếp tại thời điểm trả về) và bạn phải sử dụng chữ ký sau, bao gồm cả tên:

void sort(float* v, int n) {

}

Các ký tự được tính: những ký tự trong sorthàm, bao gồm chữ ký, cộng với các hàm bổ sung được gọi bởi nó (nhưng không bao gồm mã kiểm tra).

Chương trình phải xử lý bất kỳ giá trị số floatvà mảng có độ dài> = 0, tối đa 2 ^ 20.

Tôi sẽ cắm sortvà các phụ thuộc của nó vào một chương trình thử nghiệm và biên dịch trên GCC (không có tùy chọn ưa thích nào). Tôi sẽ cung cấp một loạt các mảng vào nó, xác minh tính chính xác của kết quả và tổng thời gian chạy. Các thử nghiệm sẽ được chạy trên Intel Core i7 740QM (Clarksfield) trong Ubuntu 13.
Độ dài mảng sẽ trải rộng trên toàn phạm vi cho phép, với mật độ mảng ngắn cao hơn. Các giá trị sẽ là ngẫu nhiên, với phân phối đuôi chất béo (cả trong phạm vi tích cực và tiêu cực). Các yếu tố trùng lặp sẽ được bao gồm trong một số thử nghiệm.
Chương trình thử nghiệm có sẵn tại đây: https://gist.github.com/anonymous/82386fa028f6534af263
Nó nhập nội dung gửi dưới dạng user.c. Số lượng trường hợp kiểm tra ( TEST_COUNT) trong điểm chuẩn thực tế sẽ là 3000. Vui lòng cung cấp bất kỳ phản hồi nào trong các nhận xét câu hỏi.

Hạn chót: 3 tuần (7 tháng 4 năm 2014, 16:00 GMT). Tôi sẽ đăng điểm chuẩn trong 2 tuần.
Có thể nên đăng gần thời hạn để tránh đưa mã của bạn cho đối thủ cạnh tranh.

Kết quả sơ bộ, như công bố điểm chuẩn:
Dưới đây là một số kết quả. Cột cuối cùng cho thấy điểm số theo tỷ lệ phần trăm, càng cao càng tốt, đưa Johnny Cage lên vị trí đầu tiên. Các thuật toán có độ lớn chậm hơn các thuật toán còn lại được chạy trên một tập hợp các bài kiểm tra và thời gian ngoại suy. Riêng của C qsortđược đưa vào để so sánh (Johnny's nhanh hơn!). Tôi sẽ thực hiện một so sánh cuối cùng vào thời gian đóng cửa.

nhập mô tả hình ảnh ở đây


3
Bạn có thể cung cấp điểm chuẩn? Các chức năng sắp xếp khác nhau thực hiện khác nhau dựa trên bản chất của dữ liệu. Ví dụ, sắp xếp bong bóng nhanh hơn so với quicksort stdlib cho các mảng nhỏ. Chúng tôi có thể muốn tối ưu hóa cho điểm chuẩn của bạn.
Claudiu

@Claudiu Tôi đã từng thấy một phiên bản quicksort ngắn đáng yêu, nó cũng chạy như mọi dữ liệu khác, nơi mọi yếu tố đều khác nhau. Nhưng nếu một số yếu tố giống nhau, nó chạy với tốc độ tuyệt đối của ốc sên. Tôi không nói về vấn đề đã biết về sự lựa chọn sai của trục trong các mảng được sắp xếp / sắp xếp một phần. Dữ liệu thử nghiệm của tôi đã được xáo trộn hoàn toàn ngẫu nhiên. Phiên bản đặc biệt này không giống như bản sao. Lạ, nhưng đúng.
Cấp sông St

3
Chào mừng đến với PPCG! Mặc dù chúng tôi không cấm các thách thức dành riêng cho ngôn ngữ, chúng tôi khuyến khích mạnh mẽ đặt ra các câu hỏi theo cách thức không biết ngôn ngữ bất cứ khi nào có thể. Hãy xem xét nó cho câu hỏi tiếp theo của bạn, và vui chơi với câu hỏi này!
Jonathan Van Matre

1
@steveverrill: Tôi không theo dõi. Không quan trọng đơn vị của bạn là gì vì dù sao bạn cũng chia tỷ lệ từ 0 lên 1. Nếu tối thiểu là 1 giờ và tối đa là 3 giờ, một cái gì đó mất 1,5 giờ sẽ là 0,25 bất kể tối thiểu là 60 phút, tối đa là 180 phút và mất 90 phút
Claudiu

1
OP chỉ nói không lắp ráp nội tuyến - ông không nói gì về nội tại.
Paul R

Câu trả lời:


6

150 ký tự

Sắp xếp nhanh chóng.

/* 146 character.
 * sizeup 1.000; speedup 1.000; */
#define REC_SIZE    \
    sort(l, v+n-l); \
    n = l-v;

/* 150 character.
 * sizeup 1.027; speedup 1.038; */
#define REC_FAST  \
    sort(v, l-v); \
    n = v+n-l;    \
    v = l;

void sort(float* v, int n)
{
    while ( n > 1 )
     {
       float* l = v-1, * r = v+n, x = v[n/2], t;
L:
       while ( *++l < x );
       while ( x < (t = *--r) );

       if (l < r)
        {
          *r = *l; *l = t;
          goto L;
        }
       REC_FAST
     }
}

Nén.

void sort(float* v, int n) {
while(n>1){float*l=v-1,*r=v+n,x=v[n/2],t;L:while(*++l<x);while(x<(t=*--r));if(l<r){*r=*l;*l=t;goto L;}sort(v,l-v);n=v+n-l;v=l;}
}

Dẫn đầu cuộc đua!
Mậu

3

150 ký tự (không có khoảng trắng)

void sort(float *v, int n) {
    int l=0;
    float t, *w=v, *z=v+(n-1)/2;

    if (n>0) {
      t=*v; *v=*z; *z=t;
      for(;++w<v+n;)
        if(*w<*v)
        {
          t=v[++l]; v[l]=*w; *w=t;
        }
      t=*v; *v=v[l]; v[l]=t;
      sort(v, l++);
      sort(v+l, n-l);
    }
}

Tuyệt vời, mục đầu tiên!
Mậu

Vui lòng gửi câu trả lời với SSE và tôi sẽ liệt kê nó trong bảng điểm, mặc dù tôi quan tâm đến các giải pháp 'di động' cho thử thách.
Mậu

if(*w<*v) { t=v[++l]; v[l]=*w; *w=t; }có thểif(*w<*v) t=v[++l], v[l]=*w, *w=t;
HỎI 17/03/2016

3

67 70 69 ký tự

Không nhanh chút nào, nhưng vô cùng nhỏ. Tôi đoán đó là sự kết hợp giữa thuật toán sắp xếp lựa chọn và bong bóng. Nếu bạn thực sự đang cố đọc điều này, thì bạn nên biết nó ++i-v-ncũng giống như vậy ++i != v+n.

void sort(float*v,int n){
    while(n--){
        float*i=v-1,t;
        while(++i-v-n)
            *i>v[n]?t=*i,*i=v[n],v[n]=t:0;
    }
}

if(a)b-> a?b:0lưu một char.
ugoren

Vâng, tất nhiên ++i-v-nlà giống như ++i != v+nchỉ trong một điều kiện, tất nhiên.
wchargein

@ugoren tôi nghĩ bạn đã đăng nhận xét đó về câu trả lời sai
HỎI 28/03/2016

@ASKASK, if(*i>v[n])...->*i>v[n]?...:0
ugoren

Bạn có chắc chắn đó là cách mà sự sắp đặt hoạt động?
ASKASK

2

123 ký tự (+3 dòng mới)

Một loại Shell tiêu chuẩn, được nén.

d,i,j;float t;
void sort(float*v,int n){
for(d=1<<20;i=d/=2;)for(;i<n;v[j]=t)for(t=v[j=i++];j>=d&&v[j-d]>t;j-=d)v[j]=v[j-d];
}  

PS: phát hiện ra nó vẫn chậm hơn 10 lần so với quicksort. Bạn cũng có thể bỏ qua mục này.


Sự lựa chọn của bạn về khoảng trống có thể tốt hơn. Đó có lẽ là lý do tại sao điều này chậm hơn rất nhiều so với quicksort. vi.wikipedia.org/wiki/Shellsort#Gap_
resultences

Tôi đã rất ngạc nhiên khi phát hiện ra chuỗi khoảng cách ảnh hưởng đến tốc độ như thế nào. Với một trình tự tốt, nó gần với quicksort nhưng vẫn chậm hơn trong kinh nghiệm của tôi.
Florian F

Đừng quá khó khăn với chính mình. Bạn đang ở vị trí thứ ba.
Kevin

2

395 nhân vật

Sáp nhập.

void sort(float* v,int n){static float t[16384];float*l,*r,*p,*q,*a=v,*b=v+n/2,
*c=v+n,x;if(n>1){sort(v,n/2);sort(v+n/2,n-n/2);while(a!=b&&b!=c)if(b-a<=c-b&&b-
a<=16384){for(p=t,q=a;q!=b;)*p++=*q++;for(p=t,q=t+(b-a);p!=q&&b!=c;)*a++=(*p<=
*b)?*p++:*b++;while(p!=q)*a++=*p++;}else{for(l=a,r=b,p=t,q=t+16384;l!=b&&r!=c&&
p!=q;)*p++=(*l<=*r)?*l++:*r++;for(q=b,b=r;l!=q;)*--r=*--q;for(q=t;p!=q;)*a++=
*q++;}}}

Định dạng.

static float* copy(const float* a, const float* b, float* out)
{   while ( a != b ) *out++ = *a++; return out;
}
static float* copy_backward(const float* a, const float* b, float* out)
{   while ( a != b ) *--out = *--b; return out;
}

static void ip_merge(float* a, float* b, float* c)
{
    /* 64K (the more memory, the better this performs). */
#define BSIZE (1024*64/sizeof(float))
    static float t[BSIZE];

    while ( a != b && b != c )
     {
       int n1 = b - a;
       int n2 = c - b;

       if (n1 <= n2 && n1 <= BSIZE)
        {
          float* p = t, * q = t + n1;
          /* copy [a,b] sequence. */
          copy(a, b, t);
          /* merge. */
          while ( p != q && b != c )
             *a++ = (*p <= *b) ? *p++ : *b++;
          /* copy remaining. */
          a = copy(p, q, a);
        }
       /* backward merge omitted. */
       else
        {
          /* there are slicker ways to do this; all require more support
           * code. */
          float* l = a, * r = b, * p = t, * q = t + BSIZE;
          /* merge until sequence end or buffer end is reached. */
          while ( l != b  && r != c && p != q )
             *p++ = (*l <= *r) ? *l++ : *r++;
          /* compact remaining. */
          copy_backward(l, b, r);
          /* copy buffer. */
          a = copy(t, p, a);
          b = r;
        }
     }
}

void sort(float* v, int n)
{
    if (n > 1)
     {
       int h = n/2;
       sort(v, h); sort(v+h, n-h); ip_merge(v, v+h, v+n);
     }
}

2

331 326 327 312 chars

Liệu radix sắp xếp 8 bit cùng một lúc. Sử dụng một bithack ưa thích để có được các phao âm để sắp xếp chính xác (bị đánh cắp từ http://stereopsis.com/radix.html ). Nó không phải là nhỏ gọn, nhưng nó thực sự nhanh (~ 8 lần so với mục sơ bộ nhanh nhất). Tôi hy vọng cho tốc độ mã giảm kích thước ...

#define I for(i=n-1;i>=0;i--)
#define J for(i=0;i<256;i++)
#define R for(r=0;r<4;r++)
#define F(p,q,k) I p[--c[k][q[i]>>8*k&255]]=q[i]

void sort(float *a, int n) {
  int *A = a,i,r,x,c[4][257],B[1<<20];
  R J c[r][i]=0;
  I {
    x=A[i]^=A[i]>>31|1<<31;
    R c[r][x>>8*r&255]++;
  }
  J R c[r][i+1]+=c[r][i];

  F(B,A,0);
  F(A,B,1);
  F(B,A,2);
  F(A,B,3)^(~B[i]>>31|1<<31);
}

2

511 424 ký tự

Radixsort tại chỗ

Cập nhật: Chuyển sang sắp xếp chèn cho kích thước mảng nhỏ hơn (tăng hiệu suất điểm chuẩn theo hệ số 4.0).

#define H p[(x^(x>>31|1<<31))>>s&255]
#define L(m) for(i=0;i<m;i++)
void R(int*a,int n,int s){if(n<64){float*i,*j,x;for(i=a+1;i<a+n;i++){x=*i;for(
j=i;a<j&&x<j[-1];j--)*j=j[-1];*j=x;}}else{int p[513]={},*q=p+257,z=255,i,j,x,t
;L(n)x=a[i],H++;L(256)p[i+1]+=q[i]=p[i];for(z=255;(i=p[z]-1)>=0;){x=a[i];while
((j=--H)!=i)t=x,x=a[j],a[j]=t;a[i]=x;while(q[z-1]==p[z])z--;}if(s)L(256)R(a+p[
i],q[i]-p[i],s-8);}}void sort(float* v,int n){R(v,n,24);}

Định dạng.

/* XXX, BITS is a power of two. */
#define BITS 8
#define BINS (1U << BITS)
#define TINY 64

#define SWAP(type, a, b) \
    do { type t=(a);(a)=(b);(b)=t; } while (0)

static inline unsigned int floatbit_to_sortable_(const unsigned int x)
{   return x ^ ((0 - (x >> 31)) | 0x80000000);
}

static inline unsigned int sortable_to_floatbit_(const unsigned int x)
{   return x ^ (((x >> 31) - 1) | 0x80000000);
}

static void insertsort_(unsigned int* a, unsigned int* last)
{
    unsigned int* i;
    for ( i = a+1; i < last; i++ )
     {
       unsigned int* j, x = *i;
       for ( j = i; a < j && x < *(j-1); j-- )
          *j = *(j-1);
       *j = x;
     }
}

static void radixsort_lower_(unsigned int* a, const unsigned int size,
  const unsigned int shift)
{
    /* @note setup cost can be prohibitive for smaller arrays, switch to
     * something that performs better in these cases. */
    if (size < TINY)
     {
       insertsort_(a, a+size);
       return;
     }

    unsigned int h0[BINS*2+1] = {}, * h1 = h0+BINS+1;
    unsigned int i, next;

    /* generate histogram. */
    for ( i = 0; i < size; i++ )
       h0[(a[i] >> shift) % BINS]++;

    /* unsigned distribution.
     * @note h0[BINS] == h1[-1] == @p size; sentinal for bin advance. */
    for ( i = 0; i < BINS; i++ )
       h0[i+1] += (h1[i] = h0[i]);

    next = BINS-1;
    while ( (i = h0[next]-1) != (unsigned int) -1 )
     {
       unsigned int x = a[i];
       unsigned int j;
       while ( (j = --h0[(x >> shift) % BINS]) != i )
          SWAP(unsigned int, x, a[j]);
       a[i] = x;
       /* advance bins.
        * @note skip full bins (zero sized bins are full by default). */
       while ( h1[(int) next-1] == h0[next] )
          next--;
     }

    /* @note bins are sorted relative to one another at this point but
     * are not sorted internally. recurse on each bin using successive
     * radii as ordering criteria. */
    if (shift != 0)
       for ( i = 0; i < BINS; i++ )
          radixsort_lower_(a + h0[i], h1[i] - h0[i], shift-BITS);
}

void sort(float* v, int n)
{
    unsigned int* a = (unsigned int*) v;
    int i;

    for ( i = 0; i < n; i++ )
       a[i] = floatbit_to_sortable_(a[i]);

    radixsort_lower_(a, n, sizeof(int)*8-BITS);

    for ( i = 0; i < n; i++ )
       a[i] = sortable_to_floatbit_(a[i]);
}

Đẹp! Hãy thử gắn cờ câu trả lời ban đầu.
Mậu

@Mau: Cảm ơn và sẽ làm. Muốn đề cập đến một lỗi trong mã điểm chuẩn. Các nhân vật void*trong qsort(dòng 88) đang bỏ qua số học con trỏ.
MojoJojoBojoHojo

1

121 114 111 ký tự

Chỉ là một bong bóng nhanh và bẩn, với đệ quy. Có lẽ không hiệu quả lắm.

void sort(float*v,int n){int i=1;float t;for(;i<n;i++)v[i-1]>(t=v[i])&&(v[i]=v[i-1],v[i-1]=t);n--?sort(v,n):0;}

Hoặc, phiên bản dài

void sort(float* values, int n) {
  int i=1;  // Start at 1, because we check v[i] vs v[i-1]
  float temp;
  for(; i < n; i++) {
    // If v[i-1] > v[i] is true (!= 0), then swap.
    // Note I am assigning values[i] to temp here. Below I want to use commas
    // so the whole thing fits into one statement, but if you assign temp there you will get sequencing issues (i.e unpredictable swap results)
    values[i - 1] > (temp = values[i]) && (
    // I tried the x=x+y,y=x-y,x=x-y trick, but using a temp
    // turns out to be shorter even if we have to declare the t variable.
      values[i] = values[i - 1], 
      values[i - 1] = temp);
  }

  // If n == 1, we are done. Otherwise, sort the first n - 1 elements recursively. 
  // The 0 is just because the third statement cannot be empty.
  n-- ? sort(values, n) : 0;
}

Ở một bên, tôi đã tìm thấy một thuật toán thực sự thú vị ở đây: rosettacode.org/wiki/Sorting_alerskyms/Pancake_sort#C Nhưng tôi không thể nén nó đủ để đánh bại 114 :)
CompuChip 17/03/2016

chương trình của bạn dường như không hoàn thành trong một số trường hợp và viết ra khỏi giới hạn trong các trường hợp khác.
Mậu

@Mau Tôi đã thử nghiệm nó trên một số đầu vào thủ công và có vẻ hoạt động tốt, nhưng do không có thời gian nên tôi đã không kiểm tra nó rất nhiều vì vậy tôi chắc chắn rằng có một số hành vi xấu ở đâu đó. Bạn có thể gửi một trường hợp thử nghiệm mà bạn gặp rắc rối không?
CompuChip

chương trình thử nghiệm có sẵn ở trên :)
Mau

Hmm Tôi đã thử chạy nó, tôi nhận được một số lỗi `munmap_chunk (): con trỏ không hợp lệ` trong phần dọn dẹp, nhưng không có gì về thử nghiệm thất bại. Tuy nhiên, bạn đúng rằng có một lỗi xảy ra và tôi dường như có một số vấn đề về trình tự (danh sách các câu lệnh được phân tách bằng dấu phẩy không làm như tôi mong đợi). Tôi sẽ cố gắng sửa nó.
CompuChip

1

221 193 172 ký tự

Heapsort - Không phải nhỏ nhất, nhưng tại chỗ và đảm bảo hành vi O (n * log (n)).

static void sink(float* a, int i, int n, float t)
{
    float* b = a+i;

    for ( ; (i = i*2+2) <= n; b = a+i )
     {
       i -= (i == n || a[i] < a[i-1]) ? 1 : 0;

       if (t < a[i])
          *b = a[i];
       else
          break;
     }
    *b = t;
}

void sort(float* a, int n)
{
    int i;
    /* make. */
    for ( i = n/2-1; i >= 0; i-- )
       sink(a, i, n, a[i]);
    /* sort. */
    for ( i = n-1; i > 0; i-- )
     {
       float t = a[i]; a[i] = a[0];
       sink(a, 0, i, t);
     }
}

Nén.

void sort(float* a,int n){
#define F(p,q,r,x,y) for(i=n/p;q>0;){t=a[i];r;for(j=x;(b=a+j,j=j*2+2)<=y&&(j-=(j==y||a[j]<a[j-1]),t<a[j]);*b=a[j]);*b=t;}
float*b,t;int i,j;F(2,i--,,i,n)F(1,--i,a[i]=*a,0,i)
}

Bạn có thể lưu một số ký tự bằng cách khấu trừ khoảng trắng. Và cũng có thể là chữ ký hàm bắt buộc, nhưng vì có một số mục được tính mà tôi đã hỏi người hỏi để làm rõ liệu nó có nên được tính không.
Jonathan Van Matre

@ user19425: Nếu bạn chạy chương trình thử nghiệm với TEST_COUNT= 3000, dường như thất bại ít nhất một thử nghiệm.
Mậu

1

154 166 ký tự

OK, đây là một quicksort dài hơn nhưng nhanh hơn.

void sort(float*v,int n){while(n>1){float*j=v,*k=v+n-1,t=*j;while(j<k){while(j<k&&*k>=t)k--;*j=*k;while(j<k&&*j<t)j++;*k=*j;}*k++=t;sort(k,v+n-k);n=j-v;}}

Đây là một sự điều chỉnh để tồn tại đầu vào được sắp xếp. Và được định dạng từ khoảng trắng không được tính.

void sort(float*v, int n){
    while(n>1){
        float*j=v, *k=j+n/2, t=*k;
        *k = *j;
        k = v+n-1;
        while(j<k){
            while(j<k && *k>=t) k--;
            *j=*k;
            while(j<k && *j<t) j++;
            *k=*j;
        }
        *k++ = t;
        sort(k,v+n-k);
        n = j-v;
    }
}

Phiên bản này dường như viết ra khỏi giới hạn trong một số trường hợp, không chấm dứt ở những người khác.
Mậu

PS: OK, nó rất chậm trên một tập hợp được sắp xếp. Nhưng báo cáo vấn đề nói đầu vào là ngẫu nhiên.
Florian F

Các giá trị là ngẫu nhiên. Tôi chưa bao giờ nói bất cứ điều gì về thứ tự họ sẽ theo :-) Nhưng đúng vậy, có những khối bao gồm khoảng 10% của tất cả các giá trị được sắp xếp theo thứ tự tăng dần và 10% khác theo thứ tự giảm dần.
Mậu

1
Đủ công bằng. Và một sort () sẽ hoạt động trên đầu vào được sắp xếp. Tôi sẽ cập nhật nội dung gửi của mình, sau đó ...
Florian F

1

150 ký tự

Shellsort (khoảng cách w / Knuth).

void sort(float* v, int n) {
float*p,x;int i,h=0;while(2*(i=h*3+1)<=n)h=i;for(;h>0;h/=3)for(i=h;i<n;i++){x=v[i];for(p=v+i-h;p>=v&&x<*p;p-=h)p[h]=*p;p[h]=x;}
}

Định dạng.

static void hsort(float* v, const int h, const int n)
{
    int i;
    for (i = h; i < n; i++) {
        float* p, x = v[i];
        for (p = v + i-h; p >= v && x < *p; p -= h)
            p[h] = *p;
        p[h] = x;
    }
}

void sort(float* v, int n)
{
    int i, h = 0;
    while (2*(i = h*3+1) <= n)
        h = i;
    for (; h > 0; h /= 3)
        hsort(v, h, n);
}

1

C 270 (đánh gôn)

#define N 1048576
void sort(float*v,int n)
{
float f[N],g;
int m[N],i,j,k,x;
g=v[0];k=0;
for(i=0;i<n;i++){for(j=0;j<n;j++){if(m[j]==1)continue;if(v[j]<g){g=v[j];k=j;}}f[i]=g;m[k]=1;for(x=0;x<n;x++){if(m[x]==0){g=v[x];k=x;break;}}}
for(i=0;i<n;i++){v[i]=f[i];}
}

Giải thích: Một mảng trống được sử dụng để lưu trữ mỗi số tối thiểu liên tiếp. Mảng int là mặt nạ có 0 biểu thị số chưa được sao chép. Sau khi nhận được giá trị tối thiểu, mặt nạ = 1 bỏ qua các số đã được sử dụng. Sau đó, mảng được sao chép trở lại ban đầu.

Tôi đã thay đổi mã để loại bỏ việc sử dụng các chức năng thư viện.


0

144

Tôi xấu hổ lấy mã của Johnny, thêm một tối ưu hóa nhỏ và nén mã theo cách rất bẩn. Nó nên ngắn hơn và nhanh hơn.

Lưu ý rằng tùy thuộc vào trình biên dịch của bạn, sort (q, v + n- ++ q) phải được thay thế bằng sort (++ q, v + nq).

#define w ;while(
void sort(float*v, int n){
    w n>1){
        float *p=v-1, *q=v+n, x=v[n/2], t
        w p<q){
            w *++p<x )
            w *--q>x );
            if( p<q ) t=*p, *p=*q, *q=t;
        }
        sort(q,v+n- ++q);
        n = p-v;
    }
}

Chà, thực ra, tôi đã bắt đầu hình thành mã của mình và tối ưu hóa nó, nhưng có vẻ như Johnny đã đưa ra tất cả các lựa chọn đúng đắn. Vì vậy, tôi đã kết thúc với gần như mã của mình. Tôi đã không nghĩ về thủ thuật goto, nhưng tôi có thể làm mà không cần.


0

228 ký tự

Thuốc phóng xạ.

void sort(float* v, int n) {
#define A(x,y,z) for(x=y;x<z;x++)
#define B h[(a[i]^(a[i]>>31|1<<31))>>j*8&255]
    int m[1<<20],*a=v,*b=m,*t,i,j;
    A(j,0,4) {
        int h[256] = {};
        A(i,0,n) B++;
        A(i,1,256) h[i] += h[i-1];
        for (i = n-1; i >= 0; i--)
            b[--B] = a[i];
        t = a, a = b, b = t;
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.