lolamontes69

K+R Exercise5_14

Sep 25th, 2014
33
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.02 KB | None | 0 0
  1. /* Modify the sorting program to handle an -r flag, which indicates sorting in
  2.  * reverse (decreasing) order. Be sure that -r works with -n.
  3.  * */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9.  
  10. #define MAXLINES 5000            /* max #lines to be sorted */
  11. #define MAXLEN 1000
  12. #define ALLOCSIZE 10000          /* size of available space */
  13.  
  14. static char allocbuf[ALLOCSIZE]; /* storage of alloc   */
  15. static char *allocp = allocbuf;  /* next free position */
  16.  
  17. char *lineptr[MAXLINES];         /* pointers to text lines */
  18.  
  19. char *alloc(int n);
  20. int readlines(char *lineptr[], int nlines);
  21. int getline(char *s, int lim);
  22. void writelines(char *lineptr[], int nlines);
  23. /* renamed because qsort() in stdlib.h */
  24. void qsort1(void *lineptr[], int left, int right, int reverse,
  25.            int (*comp)(void *, void*));      /* a pointer to a function that returns
  26.                                                 an integer and two pointers as args. */
  27. int numcmp(char *, char *);
  28. /* renamed because strcmp() in stdlib.h */
  29. int strcmp1(char *s, char *t);
  30. void swap(void *v[], int, int);
  31.  
  32.  
  33. /* sort input lines */
  34. main(int argc, char *argv[])
  35. {
  36.     int nlines;       /* number of input lines read */
  37.     int numeric = 0;  /* 1 if numeric sort */
  38.     int reverse = 0;  /* 1 if reverse sort */
  39.  
  40.     if(argc > 1 && strcmp1(argv[1], "-n") == 0)
  41.         numeric = 1;
  42.     else if(argc > 1 && strcmp1(argv[1], "-r") == 0)
  43.         reverse = 1;
  44.     if(argc > 2 && strcmp1(argv[2], "-n") == 0)
  45.         numeric = 1;
  46.     else if(argc > 2 && strcmp1(argv[2], "-r") == 0)
  47.         reverse = 1;
  48.     if((nlines = readlines(lineptr, MAXLINES)) >= 0) {
  49.         qsort1((void**) lineptr, 0, nlines-1, reverse,
  50.           (int (*)(void *,void *))(numeric ? numcmp : strcmp1)); /* pointer to function that returns
  51.                                                                   an integer with two pointers as args */
  52.         writelines(lineptr,nlines);
  53.         return 0;
  54.     }
  55.     else {
  56.         printf("input too big to sort\n");
  57.         return 1;
  58.     }
  59. }
  60.  
  61. /* alloc: return pointer to n characters */
  62. char *alloc(int n)
  63. {
  64.     if(allocbuf + ALLOCSIZE - allocp >= n) {
  65.         allocp += n;
  66.         return allocp - n;
  67.     }
  68.     else return 0;
  69. }
  70.  
  71. /* readline: read input lines */
  72. int readlines(char *lineptr[], int maxlines)
  73. {
  74.     int len, nlines;
  75.     char *p, line[MAXLEN];
  76.  
  77.     nlines = 0;
  78.     while((len=getline(line, MAXLEN))>0)
  79.         if(nlines >= maxlines || (p = alloc(len+1)) == NULL)  /* len+1 to allocate next free */
  80.             return -1;                                        /* space after '\0' */
  81.         else {
  82.             line[len]='\0'; /* delete newline */
  83.             strcpy(p, line);
  84.             lineptr[nlines++] = p;
  85.         }
  86.     return nlines;
  87. }
  88.  
  89. /* getline: get a line of input into an array */
  90. int getline(char *s, int lim)
  91. {
  92.     int c, i;
  93.  
  94.     for(i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
  95.         s[i]=c;
  96.     s[i]='\0';
  97.     return i;
  98. }
  99.  
  100. /* writelines: write output lines */
  101. void writelines(char *lineptr[], int nlines)
  102. {
  103.     int i;
  104.     puts("---- Sorted words ----");
  105.     while(nlines-- > 0)
  106.         printf("%s\n", *lineptr++);
  107. }
  108.  
  109.  
  110. /* qsort: sort v[left]...v[right] into increasing order */
  111. void qsort1(void *v[], int left, int right, int reverse,
  112.            int (*comp)(void *, void *))
  113. {
  114.     int i, last;
  115.     if(reverse==0) {
  116.         if(left >= right)  /* do nothing if array contains */
  117.             return;        /* fewer than two elements */
  118.         swap(v, left, (left + right)/2);
  119.         last = left;
  120.         for(i=left+1; i<=right; i++)
  121.             if((*comp)(v[i], v[left])<0)    /* pointer to function and args */
  122.                 swap(v, ++last, i);
  123.         swap(v,left,last);
  124.         qsort1(v, left, last-1, reverse, comp);
  125.         qsort1(v, last+1, right, reverse, comp);
  126.     }
  127.     if(reverse==1) {
  128.         if(left >= right)  /* do nothing if array contains */
  129.             return;        /* fewer than two elements */
  130.         swap(v, left, (left + right)/2);
  131.         last = left;
  132.         for(i=left+1; i<=right; i++)
  133.             if((*comp)(v[i], v[left])>0)    /* pointer to function and args */
  134.                 swap(v, ++last, i);
  135.         swap(v,left,last);
  136.         qsort1(v, left, last-1, reverse, comp);
  137.         qsort1(v, last+1, right, reverse, comp);
  138.     }
  139. }
  140.  
  141. /* numcmp: compare s1 and s2 numerically */
  142. int numcmp(char *s1, char *s2)
  143. {
  144.     double v1, v2;
  145.  
  146.     v1 = atof(s1);
  147.     v2 = atof(s2);
  148.     if(v1<v2)
  149.         return -1;
  150.     else if(v1>v2)
  151.         return 1;
  152.     else
  153.         return 0;
  154. }
  155.  
  156. /* strcmp: return <0 if s<t, O if s==t, >0 if s>t */
  157. int strcmp1(char *s, char *t)
  158. {
  159.     int i;
  160.  
  161.     for(i=0; s[i] == t[i]; i++)    /* iterate until a difference found */
  162.         if(s[i]=='\0')             /* no differences found */
  163.             return 0;
  164.     return s[i] - t[i];            /* Ascii arithmetic l-r==-6 */
  165. }
  166.  
  167. void swap(void *v[], int i, int j)
  168. {
  169.     void *temp;
  170.  
  171.     temp = v[i];
  172.     v[i] = v[j];
  173.     v[j] = temp;
  174. }
Advertisement
Add Comment
Please, Sign In to add comment