C程序设计语言(第2版)----课后练习题5-14、5-15、5-16

练习5-14 修改排序程序,使它能处理-r标记。该标记表明,以逆序(递减)方式排序。要保证-r和-n能够组合在一起使用。
练习5-15 增加选项-f,使得排序过程不考虑字母大小写之间的区别。例如,比较a和A时认为它们相等。
练习5-16 增加选项-d(代表目录顺序)。该选项表明,只对字母、数字和空格进行比较。要保证该选项可以和-f组合使用。
解:

#include
#include
#include
#include

#define REVERSE 1
#define NUMERIC 2
#define FOLD 4
#define DIR 8
#define MAXLINES 100
char *lineptr[MAXLINES];
int getline(char *line, int maxlen);
char *alloc(int len);
void afree(char *p);
int readlines(char *lineptr[],int maxlines);
int numcmp(char *s, char *t);	//数字比较
int charcmp(char *s, char *t);	//不区分大小写字母比较
int listcmp(char *s, char *t);	//只比较字母,数字,空格
int char_listcmp(char *s, char *t);		//只比较字母,数字,空格,但不区分大小写字母
void swap(void *v[], int left, int right);
void qsort(void *lineptr[], int left, int right, int(*cmp)(void *s,void *t));
void writelines(char *lineptr[], int nlines, int mode);
void Strcpy(char *s, char *t);

int main(int argc, char *argv[]) {
	int i;
	int option=0;
	int c;
	int nlines;
	if (argc > 1){
		while (--argc>0 && (*++argv)[0] == '-')
			while (c = *++argv[0])
				switch (c) {
				case 'r':
					option |= REVERSE;
					break;
				case'n':
					option |= NUMERIC;
					break;
				case'f':
					option |= FOLD;
					break;
				case'd':
					option |= DIR;
					break;
				default:
					printf("sort:illegal option %c\n", c);
					break;
				}
	}
	nlines = readlines(lineptr, MAXLINES);
	if (option&NUMERIC)
		qsort((void **)lineptr, 0, nlines - 1, (int(*)(void *, void *))numcmp);
	else if ((option&FOLD) && !(option&DIR))
		qsort((void **)lineptr, 0, nlines - 1, (int(*)(void *, void *))charcmp);
	else if ((option&DIR) && !(option&FOLD))
		qsort((void **)lineptr, 0, nlines - 1, (int(*)(void *, void *))listcmp);
	else if (option&FOLD&DIR)
		qsort((void **)lineptr, 0, nlines - 1, (int(*)(void *, void *))char_listcmp);
	else
		qsort((void **)lineptr, 0, nlines - 1, (int(*)(void *, void *))strcmp);
	writelines(lineptr, nlines, option | REVERSE);
	return 0;
}

int getline(char *line, int maxlen) {
	int i;
	char c;
	for (i = 0; (c = getchar()) != EOF &&c != '\n' &&i < maxlen - 1; i++)
		line[i] = c;
	if (c == '\n')
		line[i++] = '\n';
	line[i] = '\0';
	return i;
}

#define ALLOCSIZE 5000
static char allocbuf[ALLOCSIZE];
static char *allocp = allocbuf;
char *alloc(int len) {
	if (allocbuf + ALLOCSIZE - allocp >= len) {
		allocp += len;
		return allocp - len;
	}
	else
		return 0;
}

void afree(char *p) {
	if (p >= allocbuf && p <= allocbuf + ALLOCSIZE - 1)
		allocp = p;
}

#define MAXLEN 100
int readlines(char *lineptr[], int maxlines) {
	char line[MAXLEN];
	char *p;
	int len,nlines=0;
	while ((len = getline(line, MAXLEN)) > 0) {
		if (nlines <= maxlines && (p = alloc(len)) != NULL) {
			line[len - 1] = '\0';
			Strcpy(line, p);
			lineptr[nlines++] = p;
		}
		else
			return -1;
	}
	return nlines;
}

int numcmp(char *s, char *t) {
	double v1, v2;
	v1 = atof(s);
	v2 = atof(t);
	if (v1 >= v2)
		return 0;
	else return -1;
}

int charcmp(char *s, char *t){
	for (; *s && *t && tolower(*s) == tolower(*t); s++, t++)
		;
	if (tolower(*s) < tolower(*t))
		return -1;
	else if (tolower(*s) > tolower(*t))
		return 1;
	else
		return 0;
}

int listcmp(char *s, char *t) {
	int c1, c2;
	do
	{
		while (!isalnum(*s) && *s != ' ' && *s != '\0')
			s++;
		while (!isalnum(*t) && *t != ' ' && *t != '\0')
			t++;
		if (*s == '\0' && *t == '\0')
			return 0;
		c1 = *s;
		s++;
		c2 = *t;
		t++;
	} while (c1 == c2);

	if (c1 < c2)
		return -1;
	else
		return 1;
}

int char_listcmp(char *s, char *t) {
	int c1, c2;
	do
	{
		while (!isalnum(*s) && *s != ' ' && *s != '\0')
			s++;
		while (!isalnum(*t) && *t != ' ' && *t != '\0')
			t++;
		if (*s == '\0' && *t == '\0')
			return 0;
		c1 = tolower(*s);
		s++;
		c2 = tolower(*t);
		t++;
	} while (c1 == c2);

	if (c1 < c2)
		return -1;
	else
		return 1;
}

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

void qsort(void *v[], int left, int right, int(*cmp)(void *s, void *t)) {
	int last,i;
	if (left >= right)
		return;
	swap(v, left,(left+right)/2);
	last = left;
	for (i = left+1; i <=right; i++) {
		if ((*cmp)(v[i], v[left]) < 0)
			swap(v, ++last, i);
	}
	swap(v, left, last);
	qsort(v, left, last-1,cmp);
	qsort(v, last + 1, right, cmp);
}

void writelines(char *lineptr[], int nlines, int mode) {
	int i;
	if (!mode)
		for (i = 0; i < nlines; i++)
			printf("%s\n", lineptr[i]);
	else
		for (i = nlines-1; i >=0; i--)
			printf("%s\n", lineptr[i]);
}

void Strcpy(char *s, char *t) {
	int i;
	for (i = 0; s[i] != 0; i++)
		t[i] = s[i];
	if (s[i] == '\0')
		t[i] = '\0';	
}

你可能感兴趣的:(c程序设计语言)