第一章 开篇
来源:互联网 发布:ftp被动模式端口范围 编辑:程序博客网 时间:2024/05/17 05:15
《编程玑珠》中一些章节中有一些算法的实现,书后和网络上有源代码的例子,边看边学同时做一下记录。
如果不缺内存,如何使用一个具有库的语言来实现一种排序算法以表示和排序集合。
利用C语言中的qsort函数实现程序。
“
qsort函数是ANSI C标准中提供的,其声明在stdlib.h文件中,是根据二分法写的,其时间复杂度为n*log(n),其结构为:
void qsort(void *base, size_t nelem, size_t width, int (* comp)(const void *, const void *));
其中:
*base 为要排序的数组
nelem 为要排序的数组的长度
width 为数组元素的大小(一字节为单位)
默认的顺序是从小到大
(* comp)(const void *p1,const void *p2) 为判断大小函数的指针,这个函数需要自己定义,如果p1>p2,函数返回-1;a<b,函数返回1;a==b函数返回0。
”
//Sort input set of integers using qsort#include <stdio.h>#include <stdlib.h>int a[10000];/*int intcmp(int *x, int *y){ return (*x-*y);}*/int intcmp(const void *x, const void *y){ return *(int *)x-*(int *)y; }int main(){ int i, n=0; while(scanf("%d",&a[n])!=EOF) n++; qsort(a, n, sizeof(int), intcmp); for(i=0;i<n;i++) printf("%d ",a[i]); return 0; }
使用C++中的标准模板库中的set容器实现:
// Sort input set of integers using STL set// set容器中每个元素的值必须惟一,而且系统会根据该值自动将数据排序 #include <iostream>#include <vector>//#include <iterator>using namespace std;int main(){ int i; set<int> S; set<int>::iterator iset; while(cin>>i) S.insert(i); for(iset=S.begin();iset!=S.end();++iset) printf("%d ",*iset); /* while(*iset>0) { printf("%d ",*iset); ++iset; } */ return 0;}
使用位逻辑运算(例如与、或、移位)来实现位向量并编写程序实现位图排序,程序可以实现用10000000个bit位排序最多10000000个不同的正整数,其中每个正整数都小于10000000
使用一个数组存储数据,其中数组每一位模拟块32bit位的内存空间(1MB大概是8000000bit位),使用位运算将代表数据的某一位设置为0或1,其实是一个输入数据到位图的转换程序。注意其中的位运算符的结合性都是自左向右。程序设置了3个函数,分别完成置1,清0和检测的功能。
// Bitmap sort// Sort distinct integers in the range [0...N-1]#include <stdio.h>#define BITSPERWORD 32#define N 10000000int a[1+N/BITSPERWORD];//void set(int i){a[i/BITSPERWORD]|=((i%BITSPERWORD)<<1);}void set(int i){a[i/BITSPERWORD]|=(1<<(i%BITSPERWORD));}//void clr(int i){a[i/BITSPERWORD]&=~((i%BITSPERWORD)<<1);}void clr(int i){a[i/BITSPERWORD]&=~(1<<(i%BITSPERWORD));}//int test(int i){return a[i/BITSPERWORD]&((i%BITSPERWORD)<<1);}int test(int i){return a[i/BITSPERWORD]&(1<<(i%BITSPERWORD));}int main(){ int i; for(i=0;i<N;i++) clr(i); while(scanf("%d",&i)!=EOF) set(i); for(i=0;i<N;i++) if(test(i)) printf("%d ",i); return 0;}
程序是包括0在内的,所以题目的准确描述是10000000个不同的非负整数,每个非负整数都小于10000000。上面的程序是按照移位的思路写下来的,但源程序有另外两个宏变量:SHIFT,MASK。功能是一样的,上面的程序给的函数形参是按照十进制处理的,在多加宏变量的情况下是按照二进制处理的(不太好理解)。主函数相同。
#define BITSPERWORD 32#define SHIFT 5#define MASK 0x1F#define N 10000000int a[1 + N/BITSPERWORD];void set(int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }void clr(int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); }int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK)); }
如何生成位于0至n-1之间的k个不同的随机顺序的随机整数?尽量使你的程序简短且高效。
思路是初始化一个有序的n元数组,利用函数生成一个从0到n-1的随机数,从0开始循环k次,每次将当前数组下标值数据与该随机数标注的数组下标值数据交换,从而生成k个不同的随机数。生成随机数的函数用到stdlib库中的rand()。
// get k distinct numbers in the range [0...n-1]#include <stdio.h>#include <time.h>#include <stdlib.h> //for rand(),srand(),atoi() #define MAXN 200000int x[MAXN];// generate a random integer between a and b (including a and b)int randint(int a, int b){ //return a+(RANDMAX*rand()+rand())%(b+1-a); return a+(RAND_MAX*rand()+rand())%(b+1-a);} int main(int argc, char *argv[]){ int i,k,n,p,t; k=atoi(argv[1]); n=atoi(argv[2]); //srand(time(NULL)); srand((unsigned) time(NULL)); // for(i=0;i<n;i++) x[i]=i; for(i=0;i<k;i++) { t=randint(i,n-1); p=x[i]; x[i]=x[t]; x[t]=p; } for(i=0;i<k;i++) printf("%d\n",x[i]); return 0;}
参考资料:
C语言qsort部分:http://hi.baidu.com/zfsuan/blog/item/07a6ab1e45f6fcd8a6866952.html
位运算符的结合性:http://blog.csdn.net/qiuyang0607/article/details/6789358
rand()与srand()函数:http://blog.sina.com.cn/s/blog_5fe506110100d4ne.html
- 第一章 开篇
- 第一章 开篇
- 开篇第一章
- 开篇第一章
- 第一章 开篇
- 开篇第一章
- 第一章:开篇
- 开篇第一章
- #开篇第一章
- 开篇第一章
- 第一章:开篇
- 第一章 开篇
- 恩,开篇第一章
- 博客之开篇第一章
- 第一章、jms介绍--开篇
- 第一章 开篇(2)
- 【编程珠玑】第一章 开篇
- 【编程珠玑】第一章 开篇
- Ajax的异步通信引发的一个随机性问题<1>
- 修改sudoers让普通用户使用sudo
- 如何学好C语言
- 关于Eclipse的一些基本配置
- strstr的使用
- 第一章 开篇
- Android高手必看的十个建议
- 在linux安装虚拟机工具,实现与真机无隔阂
- LINUX的cp命令
- [C++]String类的实现
- 唐伯虎诗集
- SQL Server 中几个有用的特殊函数
- LINUX的发展(课上整理)
- GFS一些问题总结