2010-01-05 40 views
0

我在看這個節目,它讀取輸入線,然後對它們進行分類,給K & R.爲什麼這段代碼不能正確排序包含數字的行?

而且我想不通爲什麼它不對其進行排序正確,如果我例如輸入

1234532 first line 
abc second line 

它不會按升序排序。基本上,如果輸入行包含數字或其他字母,我認爲它不起作用。

但這個工程的線路,用字母:

abc 
abcsda 

將得到正確排序。

這是代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAXLINES 5000 

char *lineptr[MAXLINES]; 

int readlines(char *lineptr[], int nlines); 
void writelines(char *lineptr[], int nlines); 

void qsort(char *lineptr[], int left, int right); 

int main(int argc, char *argv[]) 
{ 
    int nlines; 

    if((nlines = readlines(lineptr, MAXLINES)) >= 0) { 
      qsort(lineptr, 0, nlines-1); 
      writelines(lineptr, nlines); 
      system("PAUSE"); 
      return 0; 
    } 
    else { 
      printf("error: input too big to sort\n"); 
      return 1; 
    } 


    system("PAUSE"); 
    return 0; 
} 


#define MAXLEN 1000 
int getline(char *, int); 
char *alloc(int); 

int readlines(char *lineptr[], int maxlines) 
{ 
    int len, nlines; 
    char *p, line[MAXLEN]; 

    nlines = 0; 
    while((len = getline(line, MAXLEN)) > 0) 
     if(nlines >= maxlines || (p = alloc(len)) == NULL) 
      return -1; 
     else { 
      line[len-1] = '\0'; 
      strcpy(p, line); 
      lineptr[nlines++] = p; 
     } 
    return nlines; 
} 

void writelines(char *lineptr[], int nlines) 
{ 
    while(nlines -- > 0) 
     printf("%s\n", *lineptr++); 
} 

int getline(char s[], int lim) 
{ 
    int c, i; 

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; i++) 
    s[i] = c;               
    if (c == '\n') { 
    s[i++] = c; 
    } 
    s[i] = '\0'; 
    return i; 
} 

#define ALLOCSIZE 10000 

static char allocbuf[ALLOCSIZE]; 
static char *allocp = allocbuf; 

char *alloc(int n) 
{ 
    if(allocbuf + ALLOCSIZE - allocp >= n) { 
      allocp +=n; 
      return allocp - n; 
    } 
    else 
      return 0; 
} 

void swap(char *v[], int i, int j) 
{ 
    char *temp; 

    temp = v[i]; 
    v[i] = v[j]; 
    v[j] = temp; 
} 

void qsort(char *v[], int left, int right) { 

    int i, last; 

    if(left >= right) 
     return; 

    swap(v, left, (left+right)/2); 
    last = left; 

    for(i = left + 1; i <= right; i++) 
     if(strcmp(v[i], v[left]) < 0) 
     swap(v, ++last, i); 

    swap(v, left, last); 
    qsort(v, left, last-1); 
    qsort(v, last+1, right); 
} 
+0

你期望你的第一個例子的順序是什麼?你應該首先得到數字線,然後是alpha線。 – 2010-01-05 18:46:20

+1

'qsort()'在'stdlib.h'中聲明(正確) - 爲什麼你要在程序中再次聲明它(而且不正確)? – 2010-01-05 18:48:14

+0

我把它按照尺寸分類, 1234123大於abc,所以我想abc應該先打印出來,而不是數字。 – Tool 2010-01-05 18:49:15

回答

6

這是正確的對它們進行排序。數字在ASCII中的字母之前排序。你期待什麼輸出?

0

它與strcmp()比較,所以它比較單個字符。如果你想比較數字,你需要添加一個選項(試圖)儘可能多地將行的開頭轉換爲數字,並在進行排序時比較轉換後的數字(並決定如何處理以非數字開頭的行)。

5

您認爲正確的排序是什麼?您可能會對字符串的內容感到困惑。從這個角度來看的

1234532 first line 
abc second line 

正確的順序是

1234532 first line 
abc second line 

因爲1進來ASCII a之前。關於此主題,我有一個以前的answer

+0

唉,我把它比作長度,而不是ASCII值。我想這可以解釋它。 – Tool 2010-01-05 18:51:20

+0

沒有。它的工作方式就像字母前面有數字的字典。查看維基百科文章以及我鏈接到的以前的答案。如果您有其他問題,請隨時在此問。 – jason 2010-01-05 18:54:48

+1

如果要按長度排序,請將'qsort()'中的if(strcmp(v [i],v [left])<0)'更改爲'if(strlen(v [i]) 2010-01-05 19:26:38

0

如果你想嚴格按行長進行排序,你需要做一個比較函數來做到這一點,並將其傳遞給qsort()。

相關問題