*****
> File Name: string_sort.c
> Author: octopus
> Mail: octopus_work.163.com
> Created Time: 2014年03月18日 星期二 12时33分19秒
************************************************************************/
#include
#include
//定义排序的最大文本行数 #define MAXLINES 100 //文本行的指针数组, 该数组中存放的是 char 类型指针 char *lineptr[MAXLINES]; //每行输入最大文本数 10 个字符 #define MAXLEN 100 int readlines(char *lineptr[], int maxlines); void writelines(char *lineptr[], int nlines); void qsort(char *v[], 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); return 0; } else { printf(error : input too big data ! ); return 1; } printf(fuck main ); return 0; } /* * 从输入流中接收收据, 最多接收 max 个字符, 返回读取到的字符串长度 * 注意 : 函数不能命名为 getline, 与stdio.h 中的 getline 命名冲突 */ int get_line(char *ch, int max, int nlines) { printf(input the %d char sequence : , nlines); int c, i; /* * getchar() 返回值 时 无符号的 char 类型转换成的 int 类型 * 将int 类型数据 赋值给 char 类型, 就是截取 int 的最后8位 即一字节赋给char变量 * * 循环的条件 : * 输入的字符数不超过 定义的 MAXLEN 10 * 获取的字符不是 EOF 结束符 * 获取的字符不是 ' ' 回车 * * 输入 EOF(Ctrl + D) 或者 回车 这一行的字符串就会输入完毕 */ for(i = 0; i < max - 1 && (c = getchar()) != EOF && c != ' '; i++) ch[i] = c; //给字符串加上结尾 '' ch[i] = ''; return i; } //可分配的内存共 11000 字节, 最大文本行数 100, 每行 100字符, 最大不会超过 10000字节 #define ALLOCSIZE 11000 //alloc函数可分配的内存存储区 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; } int readlines(char *lineptr[], int maxlines) { /* * len 获取的字符串的字符个数, 注意 不包括 '', 是真实的个数 * nlines 初始值0, 获取的字符串个数, 即字符指针数组的大小 * *p alloc()方法分配内存的个数 * line[MAXLEN] 从输入流中获取字符串的载体 */ int len, nlines; char *p, line[MAXLEN]; nlines = 0; /* * 不停的从输入流获取字符串, 放到 line 数组中, 获取的字符最多100个 * 如果获取的字符个数大于0, 就执行循环体内的方法 */ while((len = get_line(line, MAXLEN, nlines)) > 0) /* * 如果获取的字符串个数 超过 MAXLINES 100 个, 就返回 -1 * 如果没有获取到足够的内存, 就返回 -1 * 分配的内存要多分配1个, get_line 返回的函数小于 */ if(nlines >= MAXLINES || (p = alloc(len + 1)) == NULL) return -1; else { //拷贝获取的字符串 到 alloc 分配的内存中 strcpy(p, line); //将 alloc 分配的内存 指针 放入 指针数组中 lineptr[nlines++] = p; } return nlines; } /* * 输出指针数组 中 的指针 指向的字符串 * 每个指针都指向一个字符串数组, 不是常量 */ void writelines(char *lineptr[], int nlines) { int i; printf( ); //便利指针数组, 将每个指针代表的字符串打印出来 for(i = 0; i < nlines; i++) printf(lineptr[%d] = %s , i, lineptr[i]); } //数组中的两个元素进行交换 void swap(char *v[], int i, int j) { //每个数组元素都是 char * 类型的, 使用 temp 保存数组元素 char *temp; //都是 char * 之间的数据进行赋值运算 temp = v[i]; v[i] = v[j]; v[j] = temp; } /* * 参数解析 : * char *v[] : 字符指针数组 * int left : 排序的字符数组起始下标 * int right : 排序的字符数组的终止下标 * qsort(array, 0, 3) 将 array 中的 第0个 到 第3个 之间的字符串排序 * * * strcmp(s1, s2)函数解析 : * 返回值 <0 : s1 < s2 * 返回值 =0 : s1 = s2 * 返回值 >0 : s1 > s2 */ void qsort(char *v[], int left, int right) { int i, last; //如果数组的元素个数小于2个, 返回 if(left >= right) return; //交换最左边 和 中间元素 swap(v, left, (left + right) / 2); //last 记录 last = left; /* * 过程解析 : last 指向第一个元素 * 从第二个元素开始遍历整个数组, 直到遍历结束 * 如果遍历的i元素 小于 left 元素 * 将last下标自增, 然后 与 i 位置互换 * * 最终 除了 left 之外, 右边的last 个都比left小 * 将 last 与 left 互换, last 是最大的; */ for(i = left + 1; i <= right; i++) if(strcmp(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); //递归进行 left 到 中间 的排序 qsort(v, left, last - 1); //递归进行 中间 到 right 的排序 qsort(v, last + 1, right); }
运行效果 :
octopus@octopus-Vostro-270s:~/code/c/pointer$ gcc string_sort.c
octopus@octopus-Vostro-270s:~/code/c/pointer$ ./a.out
input the 0 char sequence : hello
input the 1 char sequence : world
input the 2 char sequence : fuck
input the 3 char sequence : you
input the 4 char sequence : my
input the 5 char sequence : load
input the 6 char sequence : down
input the 7 char sequence : up
input the 8 char sequence : ctrl
input the 9 char sequence : num
input the 10 char sequence : 12
input the 11 char sequence : 34
input the 12 char sequence : 56
input the 13 char sequence : 78
input the 14 char sequence : 35436
input the 15 char sequence : 6876
input the 16 char sequence :
lineptr[0] = 12
lineptr[1] = 34
lineptr[2] = 35436
lineptr[3] = 56
lineptr[4] = 6876
lineptr[5] = 78
lineptr[6] = ctrl
lineptr[7] = down
lineptr[8] = fuck
lineptr[9] = hello
lineptr[10] = load
lineptr[11] = my
lineptr[12] = num
lineptr[13] = up
lineptr[14] = world
lineptr[15] = you
4. 多维数组案例
日期转程序需求 : 将某月 某日 转换成 一年中的 第多少天, 反之 将某天转换成 某年的 某月某日;
-- 月日转天 : 如 5月1日 是某一年的第几天, 注 闰年 与 非闰年不同;
-- 天转月日 : 将天数 转换成 某一年的 月份 和 日期, 注意闰年;
|