Golfed + การคัดแยกที่รวดเร็วใน C


11

[ อัพเดทล่าสุด: โปรแกรมมาตรฐานและตัวต้านทานเบื้องต้นดูด้านล่าง]

ดังนั้นฉันต้องการทดสอบการแลกเปลี่ยนความเร็ว / ความซับซ้อนด้วยแอปพลิเคชันแบบคลาสสิก: การเรียงลำดับ

เขียนฟังก์ชัน ANSI C ที่เรียงลำดับอาร์เรย์ของจำนวนจุดลอยตัวตามลำดับที่เพิ่มขึ้น

คุณไม่สามารถใช้ใด ๆห้องสมุดโทรระบบ multithreading หรือ ASM แบบอินไลน์

ผลงานตัดสินจากสององค์ประกอบ: ความยาวโค้ดและประสิทธิภาพ การให้คะแนนดังนี้: รายการจะถูกจัดเรียงตามความยาว (บันทึกของ #characters ที่ไม่มีช่องว่างเพื่อให้คุณสามารถจัดรูปแบบบางส่วน) และตามประสิทธิภาพ (บันทึกของ #seconds มากกว่าเกณฑ์มาตรฐาน) และแต่ละช่วงเวลา [ดีที่สุดเลวร้ายที่สุด] 0,1] คะแนนรวมของโปรแกรมจะเป็นค่าเฉลี่ยของคะแนนสองมาตรฐาน คะแนนต่ำสุดชนะ หนึ่งรายการต่อผู้ใช้

การเรียงลำดับจะต้องมี (ในที่สุด) อยู่ในสถานที่ (เช่นอาร์เรย์อินพุตจะต้องมีค่าเรียงในเวลากลับ) และคุณต้องใช้ลายเซ็นต่อไปนี้รวมถึงชื่อ:

void sort(float* v, int n) {

}

ตัวอักษรที่จะถูกนับ: ตัวที่อยู่ในsortฟังก์ชั่นรวมลายเซ็นรวมถึงฟังก์ชั่นเพิ่มเติมที่เรียกได้ (แต่ไม่รวมถึงรหัสทดสอบ)

โปรแกรมจะต้องจัดการกับค่าตัวเลขใด ๆ ของfloatและอาร์เรย์ของความยาว> = 0 สูงสุด 2 ^ 20

ฉันจะเสียบsortและการอ้างอิงลงในโปรแกรมทดสอบและรวบรวม GCC (ไม่มีตัวเลือกแฟนซี) ฉันจะป้อนอาร์เรย์จำนวนมากเข้าไปในนั้นตรวจสอบความถูกต้องของผลลัพธ์และเวลาทำงานทั้งหมด การทดสอบจะดำเนินการใน Intel Core i7 740QM (Clarksfield) ภายใต้ Ubuntu 13
ความยาวของอาร์เรย์จะครอบคลุมช่วงที่อนุญาตทั้งหมดโดยมีความหนาแน่นสูงกว่าของอาร์เรย์แบบสั้น ค่าจะสุ่มโดยมีการกระจายไขมันหาง (ทั้งในช่วงบวกและลบ) องค์ประกอบที่ซ้ำจะรวมอยู่ในการทดสอบบางอย่าง
โปรแกรมการทดสอบที่มีอยู่ที่นี่: https://gist.github.com/anonymous/82386fa028f6534af263นำเข้าส่งเป็น
user.cจำนวนกรณีทดสอบ ( TEST_COUNT) ในการวัดประสิทธิภาพจริงจะเป็น 3,000 โปรดให้ข้อเสนอแนะใด ๆ ในความคิดเห็นคำถาม

กำหนดเวลา: 3 สัปดาห์ (7 เมษายน 2557, 16:00 GMT) ฉันจะโพสต์มาตรฐานใน 2 สัปดาห์
อาจแนะนำให้โพสต์ใกล้ถึงกำหนดเวลาเพื่อหลีกเลี่ยงการมอบรหัสของคุณให้กับคู่แข่ง

ผลการทดสอบเบื้องต้นตามที่ตีพิมพ์มาตรฐาน:
นี่คือผลการทดสอบบางส่วน คอลัมน์สุดท้ายแสดงคะแนนเป็นเปอร์เซ็นต์ยิ่งดียิ่งขึ้นวางจอห์นนี่เคจไว้ก่อน อัลกอริทึมที่เป็นคำสั่งของขนาดช้ากว่าที่เหลือถูกเรียกใช้บนชุดย่อยของการทดสอบและการประมาณเวลา มี C ของตัวเองqsortสำหรับการเปรียบเทียบ (จอห์นนี่เร็วกว่า!) ฉันจะทำการเปรียบเทียบขั้นสุดท้ายในเวลาปิด

ป้อนคำอธิบายรูปภาพที่นี่


3
คุณสามารถระบุมาตรฐานได้หรือไม่ ฟังก์ชันการเรียงลำดับที่แตกต่างกันทำงานแตกต่างกันไปตามลักษณะของข้อมูล เช่นการเรียงลำดับฟองจะเร็วกว่า stdlib quicksort สำหรับอาร์เรย์ขนาดเล็ก เราอาจต้องการเพิ่มประสิทธิภาพสำหรับมาตรฐานของคุณ
Claudiu

@Claudiu ฉันเคยเห็น quicksort เวอร์ชั่นสั้น ๆ ที่น่ารักซึ่งวิ่งได้ดีเหมือนกับข้อมูลอื่น ๆ ที่ทุกองค์ประกอบแตกต่างกัน แต่ถ้าองค์ประกอบบางอย่างเหมือนกันมันจะวิ่งด้วยความเร็วของหอยทาก ฉันไม่ได้พูดถึงปัญหาที่ทราบแล้วเกี่ยวกับการเลือก pivot ที่ไม่เหมาะสมในอาร์เรย์ที่เรียงลำดับ / เรียงบางส่วน ข้อมูลการทดสอบของฉันถูกสับแบบสุ่มอย่างสมบูรณ์ รุ่นนี้โดยเฉพาะไม่ชอบการทำซ้ำ แปลก แต่จริง
เลเวลริเวอร์เซนต์

3
ยินดีต้อนรับสู่ PPCG! ในขณะที่เราไม่ได้ห้ามความท้าทายเฉพาะภาษา แต่เราขอแนะนำให้ตั้งคำถามในลักษณะที่ไม่เชื่อเรื่องภาษาเมื่อใดก็ตามที่เป็นไปได้ พิจารณาคำถามต่อไปของคุณและสนุกกับเกมนี้!
Jonathan Van Matre

1
@ สตีฟเวอร์ริลล์: ฉันไม่ได้ติดตาม มันไม่สำคัญว่าหน่วยของคุณจะเป็นเพราะคุณขยายจาก 0 ถึง 1 อย่างไรก็ตาม หากขั้นต่ำคือ 1 ชั่วโมงและสูงสุดคือ 3 ชั่วโมงสิ่งที่ใช้เวลา 1.5 ชั่วโมงจะเป็น 0.25 โดยไม่คำนึงว่าขั้นต่ำคือ 60 นาทีสูงสุด 180 นาทีและใช้เวลา 90 นาที
Claudiu

1
OP เพียง แต่กล่าวว่าไม่มีการประกอบแบบอินไลน์ - เขาไม่ได้พูดอะไรเกี่ยวกับอินทริน
Paul R

คำตอบ:


6

150 ตัวอักษร

quicksort

/* 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
     }
}

การบีบอัด

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;}
}

เป็นผู้นำการแข่งขัน!
Mau

3

150 ตัวอักษร (ไม่มีช่องว่าง)

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);
    }
}

ดีเลิศรายการแรก!
Mau

อย่าลังเลที่จะโพสต์คำตอบกับ SSE และฉันจะแสดงไว้ในกระดานคะแนนแม้ว่าฉันจะสนใจโซลูชัน 'พกพา' สำหรับความท้าทาย
Mau

if(*w<*v) { t=v[++l]; v[l]=*w; *w=t; }สามารถif(*w<*v) t=v[++l], v[l]=*w, *w=t;
ASKASK

3

ตัวอักษร67 70 69

ไม่เร็วเลย แต่มีขนาดเล็กอย่างไม่น่าเชื่อ มันเป็นลูกผสมระหว่างอัลกอริธึมการเรียงลำดับการเลือกและการเรียงลำดับฟองที่ฉันเดา หากคุณกำลังพยายามอ่านสิ่งนี้จริง ๆ คุณควรรู้ว่า++i-v-nเป็นเช่น++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:0บันทึกตัวอักษร
ugoren

ดี++i-v-nเป็นเช่นเดียวกับ++i != v+nเฉพาะในเงื่อนไขของหลักสูตร
wchargin

@ugoren ฉันคิดว่าคุณโพสต์ความคิดเห็นในคำตอบที่ผิด
ASKASK

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

คุณแน่ใจหรือไม่ว่าวิธีการที่การดำรงอยู่ของสถ
ASKASK

2

123 chars (+3 newlines)

การเรียงลำดับเชลล์มาตรฐานบีบอัด

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: ค้นพบว่ามันยังช้ากว่า quicksort ถึง 10 เท่า คุณอาจละเว้นรายการนี้เช่นกัน


การเลือกช่องว่างของคุณน่าจะดีกว่า นั่นอาจเป็นเหตุผลว่าทำไมนี่จึงช้ากว่าการจัดเรียงอย่างรวดเร็ว en.wikipedia.org/wiki/Shellsort#Gap_sequences
FDinoff

ฉันประหลาดใจที่พบว่าลำดับช่องว่างมีผลต่อความเร็วมากแค่ไหน ด้วยลำดับที่ดีมันมาใกล้กับ quicksort แต่ยังช้ากว่าในประสบการณ์ของฉัน
Florian F

อย่าเป็นเรื่องยากเกินไปสำหรับตัวคุณเอง คุณอยู่ในอันดับสาม
เควิน

2

ตัวละคร 395 ตัว

mergesort

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++;}}}

ที่จัดรูปแบบ

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 ตัวอักษร

Radix เรียงลำดับ 8 บิตในแต่ละครั้งหรือไม่ ใช้ความคิดเพ้อเจ้อในการรับข้อมูลลอยเชิงลบเพื่อจัดเรียงอย่างถูกต้อง (ถูกขโมยจากhttp://stereopsis.com/radix.html ) มันไม่ใช่ขนาดกะทัดรัด แต่เร็วจริงๆ (เร็วกว่า 8x8 เท่าของการป้อนเข้าที่เร็วที่สุด) ฉันหวังว่าจะมีขนาดรหัส trumping ที่รวดเร็ว ...

#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 ตัวละคร

Inplace radixsort

อัปเดต:สวิทช์เพื่อเรียงลำดับการแทรกสำหรับขนาดอาเรย์ที่เล็กลง (เพิ่มประสิทธิภาพการวัดประสิทธิภาพโดยปัจจัย 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);}

ที่จัดรูปแบบ

/* 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]);
}

ดี! ลองตั้งค่าสถานะคำตอบดั้งเดิม
Mau

@Mau: ขอบคุณและจะทำ ต้องการพูดถึงข้อผิดพลาดในรหัสการเปรียบเทียบ การคาสต์void*ในqsort(บรรทัด 88) กำลังสลัดเลขคณิตของตัวชี้
MojoJojoBojoHojo

1

121 114 111 ตัวอักษร

เพียงแค่ Bubbleort ที่สกปรกและรวดเร็วพร้อมการเรียกซ้ำ อาจไม่มีประสิทธิภาพมากนัก

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;}

หรือรุ่นยาว

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;
}

นอกจากนี้ฉันพบอัลกอริทึมที่น่าสนใจจริง ๆ ที่นี่: rosettacode.org/wiki/Sorting_algorithms/Pancake_sort#C แต่ฉันไม่สามารถบีบอัดได้พอที่จะเอาชนะ 114 :)
CompuChip

โปรแกรมของคุณดูเหมือนจะล้มเหลวในบางกรณีและเขียนขอบเขตในกรณีอื่น ๆ
Mau

@Mau ฉันทำการทดสอบด้วยอินพุตบางตัวและดูเหมือนว่าจะทำงานได้ดี แต่เนื่องจากไม่มีเวลาฉันไม่ได้ทดสอบมันอย่างสุดซึ้งดังนั้นฉันจึงมั่นใจว่ามีบางพฤติกรรมที่ไม่ดีอยู่ที่ไหนสักแห่ง คุณช่วยโพสต์กรณีทดสอบที่คุณประสบปัญหาได้ไหม
CompuChip

มีโปรแกรมทดสอบด้านบน :)
Mau

อืมฉันพยายามเรียกใช้ฉันได้รับบางส่วนของ `munmap_chunk (): ข้อผิดพลาดของตัวชี้ที่ไม่ถูกต้อง 'ในส่วนการล้างข้อมูล แต่ไม่มีอะไรเกี่ยวกับการทดสอบที่ล้มเหลว อย่างไรก็ตามคุณมีสิทธิ์ที่จะมีข้อผิดพลาดแบบ off-by-one และฉันดูเหมือนจะมีปัญหาการเรียงลำดับ (รายการของงบที่คั่นด้วยเครื่องหมายจุลภาคไม่ได้ทำสิ่งที่ฉันคาดหวัง) ฉันจะพยายามแก้ไข
CompuChip

1

221 193 172 ตัวอักษร

Heapsort - ไม่ใช่ขนาดเล็กที่สุด แต่เข้าแทนที่และรับประกันการทำงาน 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);
     }
}

การบีบอัด

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)
}

คุณสามารถบันทึกอักขระบางตัวได้โดยการลบช่องว่าง และอาจเป็นลายเซ็นของฟังก์ชั่นบังคับ แต่เนื่องจากมีบางรายการที่นับว่าฉันได้ถามผู้ถามให้ชี้แจงว่าควรนับหรือไม่
Jonathan Van Matre

@ user19425: หากคุณรันโปรแกรมทดสอบด้วยTEST_COUNT= 3000 ดูเหมือนว่าจะล้มเหลวอย่างน้อยหนึ่งการทดสอบ
Mau

1

154 166 ตัวอักษร

ตกลงที่นี่จะเร็วกว่า แต่เร็วกว่า

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;}}

นี่คือการแก้ไขเพื่อความอยู่รอดของอินพุตที่เรียงลำดับ และจัดรูปแบบแล้วเนื่องจากพื้นที่สีขาวไม่นับ

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;
    }
}

รุ่นนี้ดูเหมือนจะเขียนออกไปจากขอบเขตในบางกรณีไม่ยุติในคนอื่น
Mau

PS: ตกลงมันช้ามากในชุดเรียงลำดับ แต่ข้อความชี้แจงปัญหาระบุว่าอินพุตนั้นสุ่ม
Florian F

ค่าเป็นแบบสุ่ม ฉันไม่เคยพูดอะไรเกี่ยวกับสิ่งที่พวกเขาต้องการใน :-) แต่ใช่มีชิ้นส่วนที่ครอบคลุมประมาณ 10% ของค่าทั้งหมดเรียงตามลำดับจากน้อยไปมากและอีก 10% ตามลำดับจากมากไปน้อย
เมา

1
ยุติธรรมพอสมควร และ sort () ควรทำงานกับอินพุตที่เรียงลำดับ ฉันจะอัปเดตการส่งของฉันแล้ว ...
Florian F

1

150 ตัวอักษร

Shellsort (w / Knuth gap)

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;}
}

ที่จัดรูปแบบ

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 (ตีกอล์ฟ)

#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];}
}

คำอธิบาย: อาร์เรย์ว่างถูกใช้เพื่อจัดเก็บแต่ละหมายเลขขั้นต่ำที่ต่อเนื่องกัน อาร์เรย์ int คือมาสก์ที่มี 0 ซึ่งระบุว่ายังไม่ได้คัดลอกหมายเลข หลังจากรับค่าต่ำสุดมาสก์ = 1 จะข้ามหมายเลขที่ใช้ไปแล้ว จากนั้นอาร์เรย์จะถูกคัดลอกกลับไปเป็นต้นฉบับ

ฉันเปลี่ยนรหัสเพื่อกำจัดการใช้ฟังก์ชั่นห้องสมุด


0

144

ฉันเอารหัสของจอห์นนี่ลงคอเพิ่มการเพิ่มประสิทธิภาพเล็กน้อยและบีบอัดรหัสในวิธีที่สกปรกมาก ควรสั้นและเร็วกว่า

โปรดทราบว่าต้องแทนที่การเรียงลำดับ (q, v + n- ++ q) โดยการเรียงลำดับ (++ 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;
    }
}

ที่จริงฉันเริ่มสร้างรหัสของฉันและปรับให้เหมาะสม แต่ดูเหมือนว่า Johnny จะทำทุกอย่างที่ถูกต้องแล้ว ดังนั้นฉันจึงลงเอยด้วยรหัสเสมือนของเขา ฉันไม่ได้คิดถึงเคล็ดลับ goto แต่ฉันสามารถทำได้โดยไม่ต้อง


0

228 ตัวอักษร

Radixsort

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;
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.