tpop

The Practice of Programming - Solutions
Log | Files | Refs

sw.c (2250B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 /* shuffle newline/whitespace terminated words */
      5 
      6 void shuffle(char *, int);
      7 int mstrlen(char *);
      8 char *mstrcpy(char *, char *);
      9 
     10 int
     11 main(void)
     12 {
     13 	int c;
     14 	char *beg, *next, *s;
     15 	int nword;
     16 	size_t siz;
     17 	
     18 	siz = 512;
     19 	beg = next = NULL;
     20 	nword = 0;
     21 
     22 	for (;(c = getc(stdin)) != EOF;)
     23 	{
     24 		if (next == NULL || (next - beg) >= (siz - 512)) 	/* first time */
     25 		{
     26 			if ((s = realloc(beg, siz)) != NULL ) {
     27 				next = s + (next - beg);
     28 				beg = s;
     29 				*next++ = c;
     30 				siz += 512;
     31 			} else {
     32 				printf("err: realloc\n");
     33 				return 1;
     34 			}
     35 		}
     36 		else if (c == '\n' || c == ' ') {
     37 			*next++ = '\0';
     38 			nword++;
     39 		}
     40 		else {
     41 			*next++ = c;
     42 		}
     43 	}
     44 
     45 	shuffle(s, nword);
     46 
     47 	for (char *t = beg; t < next;) {
     48 		printf("%s\n", t);
     49 		t += mstrlen(t) + 1;
     50 	}
     51 
     52 	free(beg);
     53 	
     54 	return 0;
     55 }
     56 
     57 void
     58 shuffle(char *s, int nword)
     59 {
     60 	char buf1[128], buf2[128];
     61 	int k, q, l;
     62 	char *str1, *str2;
     63 
     64 	for (int i = 0; i < nword && nword > 1; i++)
     65 	{
     66 		/* get two rand word indexes */
     67 		q = rand()%(nword - 1);
     68 		l = rand()%(nword - 1);
     69 
     70 		k = 0;
     71 		
     72 		for (char *t = s; k < nword; k++) {
     73 			if (k == l) 
     74 				str1 = t;
     75 			else if (k == q)
     76 				str2 = t;
     77 			t += mstrlen(t) + 1;
     78 		}
     79 
     80 		if (mstrlen(str1) > 128 || mstrlen(str2) > 128) {
     81 			printf("word too long\n");
     82 			return;
     83 		}
     84 		
     85 		if (mstrlen(str1) == mstrlen(str2)) {
     86 			mstrcpy(buf1, str1);
     87 			mstrcpy(str1, str2);
     88 			mstrcpy(str2, buf1);
     89 		}
     90 		else {
     91 			mstrcpy(buf1, str1);
     92 			mstrcpy(buf2, str2);
     93 			int t = mstrlen(str1) - mstrlen(str2);
     94 			if (str1 > str2) {
     95 				memmove((str2 + mstrlen(str2) + 1 + t), /* move words between the words being swapped */
     96 					(str2 + mstrlen(str2) + 1),
     97 					str1 - (str2 + mstrlen(str2) + 1));
     98 				mstrcpy(str2, buf1);
     99 				mstrcpy(str1 + t, buf2);
    100 			}
    101 			else if (str1 < str2) {
    102 				memmove((str1 + mstrlen(str1) + 1 - t), /* move words between the words being swapped */
    103 					(str1 + mstrlen(str1) + 1),
    104 					str2 - (str1 + mstrlen(str1) + 1));
    105 				mstrcpy(str1, buf2);
    106 				mstrcpy(str2 - t, buf1);
    107 			}
    108 		}
    109 	}
    110 }
    111 
    112 char *
    113 mstrcpy(char *a, char *b)
    114 {
    115 	int i;
    116 	
    117 	for (i = 0; b[i] != '\0'; i++)
    118 	{
    119 		a[i] = b[i];
    120 	}
    121 	a[i] = '\0';
    122 
    123 	return a;
    124 }
    125 
    126 int
    127 mstrlen(char *a)
    128 {
    129 	int i;
    130 
    131 	for (i = 0; a[i] != '\0'; i++)
    132 		;
    133 
    134 	return i;
    135 }