1 目录
2 一、数学问题 4
3 1.精度计算——大数阶乘 4
4 2.精度计算——乘法(大数乘小数) 4
5 3.精度计算——乘法(大数乘大数) 5
6 4.精度计算——加法 6
7 5.精度计算——减法 7
8 6.任意进制转换 8
9 7.最大公约数、最小公倍数 9
10 8.组合序列 10
11 9.快速傅立叶变换(FFT) 10
12 10.Ronberg算法计算积分 12
13 11.行列式计算 14
14 12.求排列组合数 15
15 13.求某一天星期几 15
16 14.卡特兰 (Catalan) 数列 原理 16
17 15.杨辉三角 16
18 16.全排列 17
19 17.匈牙利算法----最大匹配问题. 18
20 18.最佳匹配KM算法 20
21 二、字符串处理 22
22 1.字符串替换 22
23 2.字符串查找 23
24 3.字符串截取 24
25 4.LCS-最大公共子串长度 24
26 5.LCS-最大公共子串长度 25
27 6.数字转换为字符 26
28 三、计算几何 27
29 1.叉乘法求任意多边形面积 27
30 2.求三角形面积 27
31 3.两矢量间角度 28
32 4.两点距离(2D、3D) 28
33 5.射向法判断点是否在多边形内部 29
34 6.判断点是否在线段上 30
35 7.判断两线段是否相交 31
36 8.判断线段与直线是否相交 32
37 9.点到线段最短距离 32
38 10.求两直线的交点 33
39 11.判断一个封闭图形是凹集还是凸集 34
40 12.Graham扫描法寻找凸包 35
41 13.求两条线段的交点 36
42 四、数论 37
43 1.x的二进制长度 37
44 2.返回x的二进制表示中从低到高的第i位 38
45 3.模取幂运算 38
46 4.求解模线性方程 39
47 5.求解模线性方程组(中国余数定理) 39
48 6.筛法素数产生器 40
49 7.判断一个数是否素数 41
50 8.求距阵最大和 42
51 8.求一个数每一位相加之和 43
52 10.质因数分解 43
53 11.高斯消元法解线性方程组 44
54 五、图论 45
55 1.Prim算法求最小生成树 45
56 2.Dijkstra算法求单源最短路径 46
57 3.Bellman-ford算法求单源最短路径 47
58 4.Floyd-Warshall算法求每对节点间最短路径 48
59 5.解欧拉图 49
60 六、排序/查找 50
61 1.快速排序 50
62 2.希尔排序 51
63 3.选择法排序 52
64 4.二分查找 52
65 七、数据结构 53
66 1.顺序队列 53
67 2.顺序栈 56
68 3.链表 59
69 4.链栈 63
70 5.二叉树 66
71 八、高精度运算专题 68
72 1.专题函数说明 68
73 2.高精度数比较 69
74 3.高精度数加法 69
75 4.高精度数减法 70
76 5.高精度乘10 71
77 6.高精度乘单精度 71
78 7.高精度乘高精度 72
79 8.高精度除单精度 72
80 9.高精度除高精度 73
81 九、标准模板库的使用 74
82 1.计算求和 74
83 2.求数组中的最大值 76
84 3. sort和qsort 76
85 九、其他 78
86 1.运行时间计算. 78
87
88
89
90 一、数学问题
91 1.精度计算——大数阶乘
92 语法:int result=factorial(int n);
93 参数:
94 n:n 的阶乘
95 返回值:阶乘结果的位数
96 注意:
97 本程序直接输出n!的结果,需要返回结果请保留long a[]
98 需要 math.h
99 源程序:
100 int factorial(int n)
101 {
102 long a[10000];
103 int i,j,l,c,m=0,w;
104 a[0]=1;
105 for(i=1;i<=n;i++)
106 {
107 c=0;
108 for(j=0;j<=m;j++)
109 {
110 a[j]=a[j]*i+c;
111 c=a[j]/10000;
112 a[j]=a[j]%10000;
113 }
114 if(c>0) {m++;a[m]=c;}
115 }
116
117 w=m*4+log10(a[m])+1;
118 printf("\n%ld",a[m]);
119 for(i=m-1;i>=0;i--) printf("%4.4ld",a[i]);
120 return w;
121 }
122 2.精度计算——乘法(大数乘小数)
123 语法:mult(char c[],char t[],int m);
124 参数:
125 c[]:被乘数,用字符串表示,位数不限
126 t[]:结果,用字符串表示
127 m:乘数,限定10以内
128 返回值:null
129 注意:
130 需要 string.h
131 源程序:
132 void mult(char c[],char t[],int m)
133 {
134 int i,l,k,flag,add=0;
135 char s[100];
136 l=strlen(c);
137 for (i=0;i<l;i++)
138 s[l-i-1]=c[i]-'0';
139 for (i=0;i<l;i++)
140 {
141 k=s[i]*m+add;
142 if (k>=10) {s[i]=k%10;add=k/10;flag=1;} else
143 {s[i]=k;flag=0;add=0;}
144 }
145 if (flag) {l=i+1;s[i]=add;} else l=i;
146 for (i=0;i<l;i++)
147 t[l-1-i]=s[i]+'0';
148 t[l]='\0';
149 }
150 3.精度计算——乘法(大数乘大数)
151 语法:mult(char a[],char b[],char s[]);
152 参数:
153 a[]:被乘数,用字符串表示,位数不限
154 b[]:乘数,用字符串表示,位数不限
155 t[]:结果,用字符串表示
156 返回值:null
157 注意:
158 空间复杂度为 o(n^2)
159 需要 string.h
160 源程序:
161 void mult(char a[],char b[],char s[])
162 {
163 int i,j,k=0,alen,blen,sum=0,res[65][65]={0},flag=0;
164 char result[65];
165 alen=strlen(a);blen=strlen(b);
166 for (i=0;i<alen;i++)
167 for (j=0;j<blen;j++) res[i][j]=(a[i]-'0')*(b[j]-'0');
168 for (i=alen-1;i>=0;i--)
169 {
170 for (j=blen-1;j>=0;j--) sum=sum+res[i+blen-j-1][j];
171 result[k]=sum%10;
172 k=k+1;
173 sum=sum/10;
174 }
175 for (i=blen-2;i>=0;i--)
176 {
177 for (j=0;j<=i;j++) sum=sum+res[i-j][j];
178 result[k]=sum%10;
179 k=k+1;
180 sum=sum/10;
181 }
182 if (sum!=0) {result[k]=sum;k=k+1;}
183 for (i=0;i<k;i++) result[i]+='0';
184 for (i=k-1;i>=0;i--) s[i]=result[k-1-i];
185 s[k]='\0';
186 while(1)
187 {
188 if (strlen(s)!=strlen(a)&&s[0]=='0')
189 strcpy(s,s+1);
190 else
191 break;
192 }
193 }
194
195
196 4.精度计算——加法
197 语法:add(char a[],char b[],char s[]);
198 参数:
199 a[]:被加数,用字符串表示,位数不限
200 b[]:加数,用字符串表示,位数不限
201 s[]:结果,用字符串表示
202 返回值:null
203 注意:
204 空间复杂度为 o(n^2)
205 需要 string.h
206 源程序:
207 void add(char a[],char b[],char back[])
208 {
209 int i,j,k,up,x,y,z,l;
210 char *c;
211 if (strlen(a)>strlen(b)) l=strlen(a)+2; else l=strlen(b)+2;
212 c=(char *) malloc(l*sizeof(char));
213 i=strlen(a)-1;
214 j=strlen(b)-1;
215 k=0;up=0;
216 while(i>=0||j>=0)
217 {
218 if(i<0) x='0'; else x=a[i];
219 if(j<0) y='0'; else y=b[j];
220 z=x-'0'+y-'0';
221 if(up) z+=1;
222 if(z>9) {up=1;z%=10;} else up=0;
223 c[k++]=z+'0';
224 i--;j--;
225 }
226 if(up) c[k++]='1';
227 i=0;
228 c[k]='\0';
229 for(k-=1;k>=0;k--)
230 back[i++]=c[k];
231 back[i]='\0';
232 }
233
234
235 5.精度计算——减法
236 语法:sub(char s1[],char s2[],char t[]);
237 参数:
238 s1[]:被减数,用字符串表示,位数不限
239 s2[]:减数,用字符串表示,位数不限
240 t[]:结果,用字符串表示
241 返回值:null
242 注意:
243 默认s1>=s2,程序未处理负数情况
244 需要 string.h
245 源程序:
246 void sub(char s1[],char s2[],char t[])
247 {
248 int i,l2,l1,k;
249 l2=strlen(s2);l1=strlen(s1);
250 t[l1]='\0';l1--;
251 for (i=l2-1;i>=0;i--,l1--)
252 {
253 if (s1[l1]-s2[i]>=0)
254 t[l1]=s1[l1]-s2[i]+'0';
255 else
256 {
257 t[l1]=10+s1[l1]-s2[i]+'0';
258 s1[l1-1]=s1[l1-1]-1;
259 }
260 }
261 k=l1;
262 while(s1[k]<0) {s1[k]+=10;s1[k-1]-=1;k--;}
263 while(l1>=0) {t[l1]=s1[l1];l1--;}
264 loop:
265 if (t[0]=='0')
266 {
267 l1=strlen(s1);
268 for (i=0;i<l1-1;i++) t[i]=t[i+1];
269 t[l1-1]='\0';
270 goto loop;
271 }
272 if (strlen(t)==0) {t[0]='0';t[1]='\0';}
273 }
274
275
276 6.任意进制转换
277 语法:conversion(char s1[],char s2[],char t[]);
278 参数:
279 s[]:转换前的数字
280 s2[]:转换后的数字
281 d1:原进制数
282 d2:需要转换到的进制数
283 返回值:null
284 注意:
285 高于9的位数用大写'A'~'Z'表示,2~16位进制通过验证
286 源程序:
287 void conversion(char s[],char s2[],long d1,long d2)
288 {
289 long i,j,t,num;
290 char c;
291 num=0;
292 for (i=0;s[i]!='\0';i++)
293 {
294 if (s[i]<='9'&&s[i]>='0') t=s[i]-'0'; else t=s[i]-'A'+10;
295 num=num*d1+t;
296 }
297 i=0;
298 while(1)
299 {
300 t=num%d2;
301 if (t<=9) s2[i]=t+'0'; else s2[i]=t+'A'-10;
302 num/=d2;
303 if (num==0) break;
304 i++;
305 }
306 for (j=0;j<i/2;j++)
307 {c=s2[j];s2[j]=s[i-j];s2[i-j]=c;}
308 s2[i+1]='\0';
309 }
310
311
312 7.最大公约数、最小公倍数
313 语法:resulet=hcf(int a,int b)、result=lcd(int a,int b)
314 参数:
315 a:int a,求最大公约数或最小公倍数
316 b:int b,求最大公约数或最小公倍数
317 返回值:返回最大公约数(hcf)或最小公倍数(lcd)
318 注意:
319 lcd 需要连同 hcf 使用
320 源程序:
321 int hcf(int a,int b)
322 {
323 int r=0;
324 while(b!=0)
325 {
326 r=a%b;
327 a=b;
328 b=r;
329 }
330 return(a);
331 }
332 lcd(int u,int v,int h)
333 {
334 return(u*v/h);
335 }
336
337
338 8.组合序列
339 语法:m_of_n(int m, int n1, int m1, int* a, int head)
340 参数:
341 m:组合数C的上参数
342 n1:组合数C的下参数
343 m1:组合数C的上参数,递归之用
344 *a:1~n的整数序列数组
345 head:头指针
346 返回值:null
347 注意:
348 *a需要自行产生
349 初始调用时,m=m1、head=0
350 调用例子:求C(m,n)序列:m_of_n(m,n,m,a,0);
351 源程序:
352 void m_of_n(int m, int n1, int m1, int* a, int head)
353 {
354 int i,t;
355 if(m1<0 || m1>n1) return;
356 if(m1==n1)
357 {
358 return;
359 }
360 m_of_n(m,n1-1,m1,a,head); // 递归调用
361 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;
362 m_of_n(m,n1-1,m1-1,a,head+1); // 再次递归调用
363 t=a[head];a[head]=a[n1-1+head];a[n1-1+head]=t;
364 }
365
366
367 9.快速傅立叶变换(FFT)
368 语法:kkfft(double pr[],double pi[],int n,int k,double fr[],double fi[],int
369 l,int il);
370 参数:
371 pr[n]:输入的实部
372 pi[n]:数入的虚部
373 n,k:满足n=2^k
374 fr[n]:输出的实部
375 fi[n]:输出的虚部
376 l:逻辑开关,0 FFT,1 ifFT
377 il:逻辑开关,0 输出按实部/虚部;1 输出按模/幅角
378 返回值:null
379 注意:
380 需要 math.h
381 源程序:
382 void kkfft(pr,pi,n,k,fr,fi,l,il)
383 int n,k,l,il;
384 double pr[],pi[],fr[],fi[];
385 {
386 int it,m,is,i,j,nv,l0;
387 double p,q,s,vr,vi,poddr,poddi;
388 for (it=0; it<=n-1; it++)
389 {
390 m=it; is=0;
391 for (i=0; i<=k-1; i++)
392 {j=m/2; is=2*is+(m-2*j); m=j;}
393 fr[it]=pr[is]; fi[it]=pi[is];
394 }
395 pr[0]=1.0; pi[0]=0.0;
396 p=6.283185306/(1.0*n);
397 pr[1]=cos(p); pi[1]=-sin(p);
398 if (l!=0) pi[1]=-pi[1];
399 for (i=2; i<=n-1; i++)
400 {
401 p=pr[i-1]*pr[1];
402 q=pi[i-1]*pi[1];
403 s=(pr[i-1]+pi[i-1])*(pr[1]+pi[1]);
404 pr[i]=p-q; pi[i]=s-p-q;
405 }
406 for (it=0; it<=n-2; it=it+2)
407 {
408 vr=fr[it]; vi=fi[it];
409 fr[it]=vr+fr[it+1]; fi[it]=vi+fi[it+1];
410 fr[it+1]=vr-fr[it+1]; fi[it+1]=vi-fi[it+1];
411 }
412 m=n/2; nv=2;
413 for (l0=k-2; l0>=0; l0--)
414 {
415 m=m/2; nv=2*nv;
416 for (it=0; it<=(m-1)*nv; it=it+nv)
417 for (j=0; j<=(nv/2)-1; j++)
418 {
419 p=pr[m*j]*fr[it+j+nv/2];
420 q=pi[m*j]*fi[it+j+nv/2];
421 s=pr[m*j]+pi[m*j];
422 s=s*(fr[it+j+nv/2]+fi[it+j+nv/2]);
423 poddr=p-q; poddi=s-p-q;
424 fr[it+j+nv/2]=fr[it+j]-poddr;
425 fi[it+j+nv/2]=fi[it+j]-poddi;
426 fr[it+j]=fr[it+j]+poddr;
427 fi[it+j]=fi[it+j]+poddi;
428 }
429 }
430 if (l!=0)
431 for (i=0; i<=n-1; i++)
432 {
433 fr[i]=fr[i]/(1.0*n);
434 fi[i]=fi[i]/(1.0*n);
435 }
436 if (il!=0)
437 for (i=0; i<=n-1; i++)
438 {
439 pr[i]=sqrt(fr[i]*fr[i]+fi[i]*fi[i]);
440 if (fabs(fr[i])<0.000001*fabs(fi[i]))
441 {
442 if ((fi[i]*fr[i])>0) pi[i]=90.0;
443 else pi[i]=-90.0;
444 }
445 else
446 pi[i]=atan(fi[i]/fr[i])*360.0/6.283185306;
447 }
448 return;
449 }
450
451
452 10.Ronberg算法计算积分
453 语法:result=integral(double a,double b);
454 参数:
455 a:积分上限
456 b:积分下限
457 function f:积分函数
458 返回值:f在(a,b)之间的积分值
459 注意:
460 function f(x)需要自行修改,程序中用的是sina(x)/x
461 需要 math.h
462 默认精度要求是1e-5
463 源程序:
464 double f(double x)
465 {
466 return sin(x)/x; //在这里插入被积函数
467 }
468
469 double integral(double a,double b)
470 {
471 double h=b-a;
472 double t1=(1+f(b))*h/2.0;
473 int k=1;
474 double r1,r2,s1,s2,c1,c2,t2;
475 loop:
476 double s=0.0;
477 double x=a+h/2.0;
478 while(x<b)
479 {
480 s+=f(x);
481 x+=h;
482 }
483 t2=(t1+h*s)/2.0;
484 s2=t2+(t2-t1)/3.0;
485 if(k==1)
486 {
487 k++;h/=2.0;t1=t2;s1=s2;
488 goto loop;
489 }
490 c2=s2+(s2-s1)/15.0;
491 if(k==2){
492 c1=c2;k++;h/=2.0;
493 t1=t2;s1=s2;
494 goto loop;
495 }
496 r2=c2+(c2-c1)/63.0;
497 if(k==3){
498 r1=r2; c1=c2;k++;
499 h/=2.0;
500 t1=t2;s1=s2;
501 goto loop;
502 }
503 while(fabs(1-r1/r2)>1e-5){
504 r1=r2;c1=c2;k++;
505 h/=2.0;
506 t1=t2;s1=s2;
507 goto loop;
508 }
509 return r2;
510 }
511
512
513 11.行列式计算
514 语法:result=js(int s[][],int n)
515 参数:
516 s[][]:行列式存储数组
517 n:行列式维数,递归用
518 返回值:行列式值
519 注意:
520 函数中常数N为行列式维度,需自行定义
521 源程序:
522 int js(s,n)
523 int s[][N],n;
524 {
525 int z,j,k,r,total=0;
526 int b[N][N];/*b[N][N]用于存放,在矩阵s[N][N]中元素s[0]的余子式*/
527 if(n>2)
528 {
529 for(z=0;z<n;z++)
530 {
531 for(j=0;j<n-1;j++)
532 for(k=0;k<n-1;k++)
533 if(k>=z) b[j][k]=s[j+1][k+1]; else
534 b[j][k]=s[j+1][k];
535 if(z%2==0) r=s[0][z]*js(b,n-1); /*递归调用*/
536 else r=(-1)*s[0][z]*js(b,n-1);
537 total=total+r;
538 }
539 }
540 else if(n==2)
541 total=s[0][0]*s[1][1]-s[0][1]*s[1][0];
542 return total;
543 }
544
545
546 12.求排列组合数
547 语法:result=P(long n,long m); / result=long C(long n,long m);
548 参数:
549 m:排列组合的上系数
550 n:排列组合的下系数
551 返回值:排列组合数
552 注意:
553 符合数学规则:m<=n
554 源程序:
555 long P(long n,long m)
556 {
557 long p=1;
558 while(m!=0)
559 {p*=n;n--;m--;}
560 return p;
561 }
562 long C(long n,long m)
563 {
564 long i,c=1;
565 i=m;
566 while(i!=0)
567 {c*=n;n--;i--;}
568 while(m!=0)
569 {c/=m;m--;}
570 return c;
571 }
572
573
574 13.求某一天星期几
575 语法:result=weekday(int N,int M,int d)
576 参数:
577 N,M,d:年月日,例如:2003,11,4
578 返回值:0:星期天,1星期一……
579 注意:
580 需要math.h
581 适用于1582年10月15日之后, 因为罗马教皇格里高利十三世在这一天启用新历法.
582 源程序:
583 int weekday(int N,int M,int d)
584 {
585 int m,n,c,y,w;
586 m=(M-2)%12;
587 if (M>=3) n=N;else n=N-1;
588 c=n/100;
589 y=n%100;
590 w=(int)(d+floor(13*m/5)+y+floor(y/4)+floor(c/4)-2*c)%7;
591 while(w<0) w+=7;
592 return w;
593 }
594 14.卡特兰 (Catalan) 数列 原理
595 令h(1)=1,catalan数满足递归式:
596 h(n)= h(1)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(1) (其中n>=2)
597 该递推关系的解为:h(n)=c(2n-2,n-1)/n (n=1,2,3,...)
598 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, …
599 1.括号化问题。
600 矩阵链乘: P=a1×a2×a3×……×an,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,试问有几种括号化的方案?(h(n)种)
601 2.出栈次序问题。
602 一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?
603 类似:有2n个人排成一行进入剧场。入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少中方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
604 3.将多边行划分为三角形问题。
605 将一个凸多边形区域分成三角形区域的方法数?
606 类似:一位大城市的律师在她住所以北n个街区和以东n个街区处工作。每天她走2n个街区去上班。如果他
607 从不穿越(但可以碰到)从家到办公室的对角线,那么有多少条可能的道路?
608 类似:在圆上选择2n个点,将这些点成对连接起来使得所得到的n条线段不相交的方法数?
609 15.杨辉三角
610 语法: void gen()
611 预置:
612 Const int Max;
613 注意: (Max一般不能超过22,否则要用高精度计算)
614 int inta[Max][Max];
615 结果:inta为杨辉三角序列.inta[1][1]=1;inta[2][1]=1;inta[2][2]=1…
616 void gen()
617 {
618 int i ,j;
619 for( i =1 ;i <= Max ;i++)
620 {
621 inta[i][1] = 1 ;
622 inta[i][i] = 1 ;
623 }
624 inta[2][2] = 1 ;
625 for( i = 3 ; i<=Max ;i++)
626 {
627 for(j =2 ;j<i ; j++ )
628 {
629 inta[i][j] = inta[i-1][j-1] + inta[i-1][j] ;
630 }
631 }
632 }
633 前十行:
634 1
635 1 1
636 1 2 1
637 1 3 3 1
638 1 4 6 4 1
639 1 5 10 10 5 1
640 1 6 15 20 15 6 1
641 1 7 21 35 35 21 7 1
642 1 8 28 56 70 56 28 8 1
643 1 9 36 84 126 126 84 36 9 1
644
645 16.全排列
646 语法: void qp(int Array[],int begin,int end);
647 注意:当参与全排列的数字稍大的时候将会有很大的计算量
648
649 #include<iostream>
650 using namespace std;
651 const int MaxNum=20;
652 static int a[MaxNum];
653 void qp(int Array[],int begin,int end);
654 int main()
655 {
656 int i;
657 for(i=0;i<MaxNum;i++)
658 a[i]=i+1;
659 //初始化数组为:1,2,3..
660 qp(a,0,10);
661 return 0;
662 }
663 void qp(int Array[],int begin,int end)
664 {
665 int i;
666 if(begin>=end)
667 {
668 for(i=0;i<end;i++)
669 cout<<Array[i]<<"\t";
670 cout<<endl;
671 }
672 else for(i=begin;i<end;i++)
673 {
674 swap(a[begin],a[i]);
675 qp(a,begin+1,end);
676 swap(a[begin],a[i]);
677 }
678 }
679
680
681 //stl里面的全排列生成函数next_permutation
682 #include<iostream>
683 #include <algorithm>
684 using namespace std;
685
686 int main()
687 {
688 int i;
689 int A[] = {0,1,2,3};
690 while(next_permutation(A, A+4)==true) //prev_permutation(A, A+4);
691
692 {
693 for(i=0;i<4;i++)
694 cout<<A[i]<<"\t";
695 cout<<endl;
696
697 }
698 }
699 17.匈牙利算法----最大匹配问题.
700 #include<stdio.h>
701 #include<string.h>
702 bool g[201][201]; //为边之间的关系,如g[0][1]==true表示为左边0点可与右边1点相连.
703 int n,m,ans; //n左边的点,m右边的点,ans为最大匹配的边数.
704 bool b[201]; //b[i]表示该点是否有左边的点连上
705 int link[201];
706 bool init()
707 {
708 int _x,_y;
709 memset(g,0,sizeof(g)); //对二维数组也可以这样初始化!
710 memset(link,0,sizeof(link));
711 ans=0;
712 if(scanf("%d%d",&n,&m)==EOF)return false;
713 for(int i=1;i<=n;i++) //n左边的点,m右边的点
714 {
715 scanf("%d",&_x);
716 for(int j=0;j<_x;j++)
717 {
718 scanf("%d",&_y);
719 g[ i ][_y]=true;
720 }
721 }
722 return true;
723 }
724 bool find(int a)
725 {
726 for(int i=1;i<=m;i++)
727 {
728 if(g[a][ i ]==true&&!b[ i ])
729 {
730 b[ i ]=true;
731 if(link[ i ]==0||find(link[ i ]))
732 {
733 link[ i ]=a;
734 return true;
735 }
736 }
737 }
738 return false;
739 }
740 int main()
741 {
742 while(init())
743 {
744 for(int i=1;i<=n;i++)
745 {
746 memset(b,0,sizeof(b)); //
747 if(find(i))
748 ans++;
749 }
750 printf("%d\n",ans);
751 }
752 }
753 18.最佳匹配KM算法
754 #include <cstdio>
755 #include <queue>
756 #include <algorithm>
757 using namespace std;
758 const int N = 301;
759 const int INF = 10000;
760
761 class Graph
762 {
763 private:
764 bool xckd[N], yckd[N];
765 int n, edge[N][N], xmate[N], ymate[N];
766 int lx[N], ly[N], slack[N], prev[N];
767 queue<int> Q;
768 bool bfs();
769 void agument(int);
770 public:
771 bool make();
772 int KMMatch();
773 };
774 bool Graph::make()
775 {
776 int i, j;
777 while(scanf("%d", &n) != EOF)
778 {
779 for(i = 0; i < n; i++)
780 {
781 for(j = 0; j < n; j++)
782 {
783 scanf("%d", &edge[i][j]);
784 }
785 }
786 return true;
787 }
788 return false;
789 }
790 bool Graph::bfs() {
791 while(!Q.empty()) {
792 int p = Q.front(), u = p>>1; Q.pop();
793 if(p&1) {
794 if(ymate[u] == -1) { agument(u); return true; }
795 else { xckd[ymate[u]] = true; Q.push(ymate[u]<<1); }
796 } else {
797 for(int i = 0; i < n; i++)
798 if(yckd[i]) continue;
799 else if(lx[u]+ly[i] != edge[u][i]) {
800 int ex = lx[u]+ly[i]-edge[u][i];
801 if(slack[i] > ex) { slack[i] = ex; prev[i] = u; }
802 } else {
803 yckd[i] = true; prev[i] = u;
804 Q.push((i<<1)|1);
805 }
806 }
807 }
808 return false;
809 }
810 void Graph::agument(int u) {
811 while(u != -1) {
812 int pv = xmate[prev[u]];
813 ymate[u] = prev[u]; xmate[prev[u]] = u;
814 u = pv;
815 }
816 }
817 int Graph::KMMatch()
818 {
819 int i, j;
820 memset(ly, 0, sizeof(ly));
821 for(i = 0; i < n; i++) {
822 lx[i] = -INF;
823 for(j = 0; j < n; j++)
824 lx[i] = lx[i] > edge[i][j] ? lx[i] : edge[i][j];
825 }
826 memset(xmate, -1, sizeof(xmate)); memset(ymate, -1, sizeof(ymate));
827 bool agu = true;
828 for(int mn = 0; mn < n; mn++) {
829 if(agu) {
830 memset(xckd, false, sizeof(xckd));
831 memset(yckd, false, sizeof(yckd));
832 for(i = 0; i < n; i++) slack[i] = INF;
833 while(!Q.empty()) Q.pop();
834 xckd[mn] = true; Q.push(mn<<1);
835 }
836 if(bfs()) { agu = true; continue; }
837 int ex = INF; mn--; agu = false;
838 for(i = 0; i < n; i++)
839 if(!yckd[i]) ex = ex < slack[i] ? ex : slack[i];
840 for(i = 0; i < n; i++) {
841 if(xckd[i]) lx[i] -= ex;
842 if(yckd[i]) ly[i] += ex;
843 slack[i] -= ex;
844 }
845 for(int i = 0; i < n; i++)
846 if(!yckd[i] && slack[i] == 0) { yckd[i] = true; Q.push((i<<1)|1); }
847 }
848 int cost = 0;
849 for(i = 0; i < n; i++) cost += edge[i][xmate[i]];
850 return cost;
851 }
852 int main()
853 {
854 Graph g;
855 while(g.make())
856 {
857 printf("%d\n", g.KMMatch());
858 }
859 return 0;
860 }
861 二、字符串处理
862 1.字符串替换
863 语法:replace(char str[],char key[],char swap[]);
864 参数:
865 str[]:在此源字符串进行替换操作
866 key[]:被替换的字符串,不能为空串
867 swap[]:替换的字符串,可以为空串,为空串表示在源字符中删除key[]
868 返回值:null
869 注意:
870 默认str[]长度小于1000,如否,重新设定设定tmp大小
871 需要 string.h
872 源程序:
873 void replace(char str[],char key[],char swap[])
874 {
875 int l1,l2,l3,i,j,flag;
876 char tmp[1000];
877 l1=strlen(str);
878 l2=strlen(key);
879 l3=strlen(swap);
880 for (i=0;i<=l1-l2;i++)
881 {
882 flag=1;
883 for (j=0;j<l2;j++)
884 if (str[i+j]!=key[j]) {flag=0;break;}
885 if (flag)
886 {
887 strcpy(tmp,str);
888 strcpy(&tmp[i],swap);
889 strcpy(&tmp[i+l3],&str[i+l2]);
890 strcpy(str,tmp);
891 i+=l3-1;
892 l1=strlen(str);
893 }
894 }
895 }
896
897
898 2.字符串查找
899 语法:result=strfind(char str[],char key[]);
900 参数:
901 str[]:在此源字符串进行查找操作
902 key[]:被查找的字符串,不能为空串
903 返回值:如果查找成功,返回key在str中第一次出现的位置,否则返回-1
904 注意:
905 需要 string.h
906 源程序:
907 int strfind(char str[],char key[])
908 {
909 int l1,l2,i,j,flag;
910 l1=strlen(str);
911 l2=strlen(key);
912 for (i=0;i<=l1-l2;i++)
913 {
914 flag=1;
915 for (j=0;j<l2;j++)
916 if (str[i+j]!=key[j]) {flag=0;break;}
917 if (flag) return i;
918 }
919 return -1;
920 }
921
922
923 3.字符串截取
924 语法:mid(char str[],int start,int len,char strback[])
925 参数:
926 str[]:操作的目标字符串
927 start:从第start个字符串开始,截取长度为len的字符
928 len:从第start个字符串开始,截取长度为len的字符
929 strback[]:截取的到的字符
930 返回值:0:超出字符串长度,截取失败;1:截取成功
931 注意:
932 需要 string.h
933 源程序:
934 int mid(char str[],int start,int len,char strback[])
935 {
936 int l,i,k=0;
937 l=strlen(str);
938 if (start+len>l) return 0;
939 for (i=start;i<start+len;i++)
940 strback[k++]=str[i];
941 strback[k]='\0';
942 return 1;
943 }
944
945
946 4.LCS-最大公共子串长度
947 语法:result=lcs_len(char *a, char *b);
948 参数:
949 a,b[]:根据a,b生成最大公共子串
950 返回值:最大公共子串的长度
951 注意:
952 需要 string.h
953 M、N是a,b数组的最大可能长度
954 如果不需要生成公共子串,c[M][N]不可设置为全局变量
955 源程序:
956 #define M 20
957 #define N 20
958 int c[M][N];
959 int lcs_len(char *a, char *b)
960 {
961 int m=strlen(a),n=strlen(b),i,j;
962 for(i=0;i<=m;i++) c[i][0]=0;
963 for(j=0;j<=n;j++) c[0][j]=0;
964 for(i=1;i<=m;i++)
965 for(j=1;j<=n;j++)
966 {
967 if(a[i-1]==b[j-1])
968 c[i][j]=c[i-1][j-1]+1;
969 else if(c[i-1][j]>c[i][j-1])
970 c[i][j]=c[i-1][j];
971 else
972 c[i][j]=c[i][j-1];
973 }
974 return c[m][n];
975 }
976
977
978 5.LCS-最大公共子串长度
979 语法:result=build_lcs(char s[], char *a, int blen, int clen);
980 参数:
981 *a:生成公共子串的字符串a,b中的a
982 s[]:接受返回结果的字符串数组
983 blen:生成公共子串的字符串a,b中的b的长度
984 clen:最大公共子串的长度,通过lcs_len函数求得
985 返回值:最大公共子串的长度
986 注意:
987 需要 string.h
988 需要lcs_len函数求clen并且生成c[M][N]
989 可通过result=build_lcs返回指针或者通过build_lcs(s,a,blen,clen),用s接受结果
990 源程序:
991 char *build_lcs(char s[], char *a, int blen, int clen)
992 {
993 int k=clen,alen=strlen(a),i,j;
994 s[k]='\0';
995 i=alen,j=blen;
996 while(k>0)
997 {
998 if(c[i][j]==c[i-1][j])
999 i--;
1000 else if(c[i][j]==c[i][j-1])
1001 j--;
1002 else
1003 {
1004 s[--k]=a[i-1];
1005 i--;j--;
1006 }
1007 }
1008 return s;
1009 }
1010
1011
1012 6.数字转换为字符
1013 语法:cstr(int k,char o[]);
1014 参数:
1015 k:转换的数字
1016 o[]:存储转换结果的字符串
1017 返回值:null
1018 注意:
1019 需要 math.h
1020 源程序:
1021 void cstr(int k,char o[])
1022 {
1023 int len,i,t;
1024 len=log10(k)+1;
1025 for (i=len;i>0;i--)
1026 {
1027 t=k%10;
1028 k-=t;k/=10;
1029 o[i-1]='0'+t;
1030 }
1031 o[len]='\0';
1032 }
1033
1034
1035 三、计算几何
1036 1.叉乘法求任意多边形面积
1037 语法:result=polygonarea(Point *polygon,int N);
1038 参数:
1039 *polygon:多变形顶点数组
1040 N:多边形顶点数目
1041 返回值:多边形面积
1042 注意:
1043 支持任意多边形,凹、凸皆可
1044 多边形顶点输入时按顺时针顺序排列
1045 源程序:
1046 typedef struct {
1047 double x,y;
1048 } Point;
1049 double polygonarea(Point *polygon,int N)
1050 {
1051 int i,j;
1052 double area = 0;
1053 for (i=0;i<N;i++) {
1054 j = (i + 1) % N;
1055 area += polygon[i].x * polygon[j].y;
1056 area -= polygon[i].y * polygon[j].x;
1057 }
1058 area /= 2;
1059 return(area < 0 ? -area : area);
1060 }
1061
1062
1063 2.求三角形面积
1064 语法:result=area3(float x1,float y1,float x2,float y2,float x3,float y3);
1065 参数:
1066 x1~3:三角形3个顶点x坐标
1067 y1~3:三角形3个顶点y坐标
1068 返回值:三角形面积
1069 注意:
1070 需要 math.h
1071 源程序:
1072 float area3(float x1,float y1,float x2,float y2,float x3,float y3)
1073 {
1074 float a,b,c,p,s;
1075 a=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1076 b=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
1077 c=sqrt((x3-x2)*(x3-x2)+(y3-y2)*(y3-y2));
1078 p=(a+b+c)/2;
1079 s=sqrt(p*(p-a)*(p-b)*(p-c));
1080 return s;
1081 }
1082
1083
1084 3.两矢量间角度
1085 语法:result=angle(double x1, double y1, double x2, double y2);
1086 参数:
1087 x/y1~2:两矢量的坐标
1088 返回值:两的角度矢量
1089 注意:
1090 返回角度为弧度制,并且以逆时针方向为正方向
1091 需要 math.h
1092 源程序:
1093 #define PI 3.1415926
1094
1095 double angle(double x1, double y1, double x2, double y2)
1096 {
1097 double dtheta,theta1,theta2;
1098 theta1 = atan2(y1,x1);
1099 theta2 = atan2(y2,x2);
1100 dtheta = theta2 - theta1;
1101 while (dtheta > PI)
1102 dtheta -= PI*2;
1103 while (dtheta < -PI)
1104 dtheta += PI*2;
1105 return(dtheta);
1106 }
1107
1108
1109 4.两点距离(2D、3D)
1110 语法:result=distance_2d(float x1,float x2,float y1,float y2);
1111 参数:
1112 x/y/z1~2:各点的x、y、z坐标
1113 返回值:两点之间的距离
1114 注意:
1115 需要 math.h
1116 源程序:
1117 float distance_2d(float x1,float x2,float y1,float y2)
1118 {
1119 return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
1120 }
1121
1122
1123 float distance_3d(float x1,float x2,float y1,float y2,float z1,float z2)
1124 {
1125 return(sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2)));
1126 }
1127
1128
1129 5.射向法判断点是否在多边形内部
1130 语法:result=insidepolygon(Point *polygon,int N,Point p);
1131 参数:
1132 *polygon:多边形顶点数组
1133 N:多边形顶点个数
1134 p:被判断点
1135 返回值:0:点在多边形内部;1:点在多边形外部
1136 注意:
1137 若p点在多边形顶点或者边上,返回值不确定,需另行判断
1138 需要 math.h
1139 源程序:
1140 #define MIN(x,y) (x < y ? x : y)
1141 #define MAX(x,y) (x > y ? x : y)
1142 typedef struct {
1143 double x,y;
1144 } Point;
1145 int insidepolygon(Point *polygon,int N,Point p)
1146 {
1147 int counter = 0;
1148 int i;
1149 double xinters;
1150 Point p1,p2;
1151 p1 = polygon[0];
1152 for (i=1;i<=N;i++) {
1153 p2 = polygon[i % N];
1154 if (p.y > MIN(p1.y,p2.y)) {
1155 if (p.y <= MAX(p1.y,p2.y)) {
1156 if (p.x <= MAX(p1.x,p2.x)) {
1157 if (p1.y != p2.y) {
1158 xinters = (p.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
1159 if (p1.x == p2.x || p.x <= xinters)
1160 counter++;
1161 }
1162 }
1163 }
1164 }
1165 p1 = p2;
1166 }
1167 if (counter % 2 == 0)
1168 return(OUTSIDE);
1169 else
1170 return(INSIDE);
1171 }
1172
1173
1174 6.判断点是否在线段上
1175 语法:result=Pointonline(Point p1,Point p2,Point p);
1176 参数:
1177 p1、p2:线段的两个端点
1178 p:被判断点
1179 返回值:0:点在不在线段上;1:点在线段上
1180 注意:
1181 若p线段端点上返回1
1182 需要 math.h
1183 源程序:
1184 #define MIN(x,y) (x < y ? x : y)
1185 #define MAX(x,y) (x > y ? x : y)
1186 typedef struct {
1187 double x,y;
1188 } Point;
1189 int FC(double x1,double x2)
1190 {
1191 if (x1-x2<0.000002&&x1-x2>-0.000002) return 1; else return 0;
1192 }
1193
1194
1195 int Pointonline(Point p1,Point p2,Point p)
1196 {
1197 double x1,y1,x2,y2;
1198 x1=p.x-p1.x;
1199 x2=p2.x-p1.x;
1200 y1=p.y-p1.y;
1201 y2=p2.y-p1.y;
1202 if (FC(x1*y2-x2*y1,0)==0) return 0;
1203 if ((MIN(p1.x,p2.x)<=p.x&&p.x<=MAX(p1.x,p2.x))&&
1204 (MIN(p1.y,p2.y)<=p.y&&p.y<=MAX(p1.y,p2.y)))
1205 return 1; else return 0;
1206 }
1207
1208
1209 7.判断两线段是否相交
1210 语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);
1211 参数:
1212 p1~4:两条线段的四个端点
1213 返回值:0:两线段不相交;1:两线段相交;2两线段首尾相接
1214 注意:
1215 p1!=p2;p3!=p4;
1216 源程序:
1217 #define MIN(x,y) (x < y ? x : y)
1218 #define MAX(x,y) (x > y ? x : y)
1219 typedef struct {
1220 double x,y;
1221 } Point;
1222 int lineintersect(Point p1,Point p2,Point p3,Point p4)
1223 {
1224 Point tp1,tp2,tp3;
1225 if
1226 ((p1.x==p3.x&&p1.y==p3.y)||(p1.x==p4.x&&p1.y==p4.y)||(p2.x==p3.x&&p2.y==p3.y)||(p2.x==p4.x&&p2.y==p4.y))
1227 return 2;
1228 //快速排斥试验
1229 if
1230 ((MIN(p1.x,p2.x)<=p3.x&&p3.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p3.y&&p3.y<=MAX(p1.y,p2.y))||
1231
1232 (MIN(p1.x,p2.x)<=p4.x&&p4.x<=MAX(p1.x,p2.x)&&MIN(p1.y,p2.y)<=p4.y&&p4.y<=MAX(p1.y,p2.y)))
1233 ;else return 0;
1234 //跨立试验
1235 tp1.x=p1.x-p3.x;
1236 tp1.y=p1.y-p3.y;
1237 tp2.x=p4.x-p3.x;
1238 tp2.y=p4.y-p3.y;
1239 tp3.x=p2.x-p3.x;
1240 tp3.y=p2.y-p3.y;
1241 if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1;
1242 else return 0;
1243 }
1244
1245
1246 8.判断线段与直线是否相交
1247 语法:result=lineintersect(Point p1,Point p2,Point p3,Point p4);
1248 参数:
1249 p1、p2:线段的两个端点
1250 p3、p4:直线上的两个点
1251 返回值:0:线段直线不相交;1:线段和直线相交
1252 注意:
1253 如线段在直线上,返回 1
1254 源程序:
1255 typedef struct {
1256 double x,y;
1257 } Point;
1258 int lineintersect(Point p1,Point p2,Point p3,Point p4)
1259 {
1260 Point tp1,tp2,tp3;
1261 tp1.x=p1.x-p3.x;
1262 tp1.y=p1.y-p3.y;
1263 tp2.x=p4.x-p3.x;
1264 tp2.y=p4.y-p3.y;
1265 tp3.x=p2.x-p3.x;
1266 tp3.y=p2.y-p3.y;
1267 if ((tp1.x*tp2.y-tp1.y*tp2.x)*(tp2.x*tp3.y-tp2.y*tp3.x)>=0) return 1;
1268 else return 0;
1269 }
1270
1271
1272 9.点到线段最短距离
1273 语法:result=mindistance(Point p1,Point p2,Point q);
1274 参数:
1275 p1、p2:线段的两个端点
1276 q:判断点
1277 返回值:点q到线段p1p2的距离
1278 注意:
1279 需要 math.h
1280 源程序:
1281 #define MIN(x,y) (x < y ? x : y)
1282 #define MAX(x,y) (x > y ? x : y)
1283 typedef struct {
1284 double x,y;
1285 } Point;
1286 double mindistance(Point p1,Point p2,Point q)
1287 {
1288 int flag=1;
1289 double k;
1290 Point s;
1291 if (p1.x==p2.x) {s.x=p1.x;s.y=q.y;flag=0;}
1292 if (p1.y==p2.y) {s.x=q.x;s.y=p1.y;flag=0;}
1293 if (flag)
1294 {
1295 k=(p2.y-p1.y)/(p2.x-p1.x);
1296 s.x=(k*k*p1.x+k*(q.y-p1.y)+q.x)/(k*k+1);
1297 s.y=k*(s.x-p1.x)+p1.y;
1298 }
1299 if (MIN(p1.x,p2.x)<=s.x&&s.x<=MAX(p1.x,p2.x))
1300 return sqrt((q.x-s.x)*(q.x-s.x)+(q.y-s.y)*(q.y-s.y));
1301 else
1302 return
1303 MIN(sqrt((q.x-p1.x)*(q.x-p1.x)+(q.y-p1.y)*(q.y-p1.y)),sqrt((q.x-p2.x)*(q.x-p2.x)+(q.y-p2.y)*(q.y-p2.y)));
1304 }
1305
1306
1307 10.求两直线的交点
1308 语法:result=mindistance(Point p1,Point p2,Point q);
1309 参数:
1310 p1~p4:直线上不相同的两点
1311 *p:通过指针返回结果
1312 返回值:1:两直线相交;2:两直线平行
1313 注意:
1314 如需要判断两线段交点,检验k和对应k1(注释中)的值是否在0~1之间,用在0~1之间的那个求交点
1315 源程序:
1316 typedef struct {
1317 double x,y;
1318 } Point;
1319 int linecorss(Point p1,Point p2,Point p3,Point p4,Point *p)
1320 {
1321 double k;
1322 if ((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y)==0) return 0;
1323 if ((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x)==0&&
1324 (p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x)==0) return 0;
1325
1326 k=((p4.x-p3.x)*(p1.y-p3.y)-(p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
1327 //k1=((p2.x-p1.x)*(p1.y-p3.y)-(p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x)-(p4.x-p3.x)*(p2.y-p1.y));
1328 (*p).x=p1.x+k*(p2.x-p1.x);
1329 (*p).y=p1.y+k*(p2.y-p1.y);
1330 return 1;
1331 }
1332
1333
1334 11.判断一个封闭图形是凹集还是凸集
1335 语法:result=convex(Point *p,int n);
1336 参数:
1337 *p:封闭曲线顶点数组
1338 n:封闭曲线顶点个数
1339 返回值:1:凸集;-1:凹集;0:曲线不符合要求无法计算
1340 注意:
1341 默认曲线为简单曲线:无交叉、无圈
1342 源程序:
1343 typedef struct {
1344 double x,y;
1345 } Point;
1346 int convex(Point *p,int n)
1347 {
1348 int i,j,k;
1349 int flag = 0;
1350 double z;
1351 if (n < 3)
1352 return(0);
1353 for (i=0;i<n;i++) {
1354 j = (i + 1) % n;
1355 k = (i + 2) % n;
1356 z = (p[j].x - p[i].x) * (p[k].y - p[j].y);
1357 z -= (p[j].y - p[i].y) * (p[k].x - p[j].x);
1358 if (z < 0)
1359 flag |= 1;
1360 else if (z > 0)
1361 flag |= 2;
1362 if (flag == 3)
1363 return -1; //CONCAVE
1364 }
1365 if (flag != 0)
1366 return 1; //CONVEX
1367 else
1368 return 0;
1369 }
1370
1371
1372 12.Graham扫描法寻找凸包
1373 语法:Graham_scan(Point PointSet[],Point ch[],int n,int &len);
1374 参数:
1375 PointSet[]:输入的点集
1376 ch[]:输出的凸包上的点集,按照逆时针方向排列
1377 n:PointSet中的点的数目
1378 len:输出的凸包上的点的个数
1379 返回值:null
1380 源程序:
1381 struct Point{
1382 float x,y;
1383 };
1384 float multiply(Point p1,Point p2,Point p0)
1385 {
1386 return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
1387 }
1388 float distance(Point p1,Point p2)
1389 {
1390 return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
1391 }
1392 void Graham_scan(Point PointSet[],Point ch[],int n,int &len)
1393 {
1394 int i,j,k=0,top=2;
1395 Point tmp;
1396
1397 for(i=1;i<n;i++)
1398 if
1399 ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))
1400 k=i;
1401 tmp=PointSet[0];
1402 PointSet[0]=PointSet[k];
1403 PointSet[k]=tmp;
1404 for (i=1;i<n-1;i++)
1405 {
1406 k=i;
1407 for (j=i+1;j<n;j++)
1408 if ( (multiply(PointSet[j],PointSet[k],PointSet[0])>0) ||
1409 ((multiply(PointSet[j],PointSet[k],PointSet[0])==0)
1410
1411 &&(distance(PointSet[0],PointSet[j])<distance(PointSet[0],PointSet[k])))
1412 )
1413 k=j;
1414 tmp=PointSet[i];
1415 PointSet[i]=PointSet[k];
1416 PointSet[k]=tmp;
1417 }
1418 ch[0]=PointSet[0];
1419 ch[1]=PointSet[1];
1420 ch[2]=PointSet[2];
1421 for (i=3;i<n;i++)
1422 {
1423 while (multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
1424 ch[++top]=PointSet[i];
1425 }
1426 len=top+1;
1427 }
1428
1429
1430 13.求两条线段的交点
1431 语法:Result=IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p);
1432 参数:
1433 P1~P4:两条线断4个端点
1434 P:线段交点
1435 返回值:如果两条线段平行无交点,返回 0,否则返回 1
1436 源程序:
1437 struct Point{
1438 float x,y;
1439 };
1440
1441 int IntersectPoint (Point p1,Point p2,Point p3,Point p4,Point &p)
1442 {
1443 float a,b,c,d,e,f;
1444 a=p2.y-p1.y;
1445 b=p1.x-p2.x;
1446 c=p1.y*(p2.x-p1.x)+p1.x*(p2.y-p1.y);
1447 d=p4.y-p3.y;
1448 e=p3.x-p4.x;
1449 f=p3.y*(p4.x-p3.x)+p1.x*(p4.y-p3.y);
1450 if (a*e==b*d)
1451 return 0;
1452 else
1453 {
1454 p.x=(e*c-b*f)/(b*d-a*e);
1455 p.y=(d*c-a*f)/(a*e-b*d);
1456 return 1;
1457 }
1458 }
1459
1460
1461 四、数论
1462 1.x的二进制长度
1463 语法:result=BitLength(int x);
1464 参数:
1465 x:测长的x
1466 返回值:x的二进制长度
1467 源程序:
1468 int BitLength(int x)
1469 {
1470 int d = 0;
1471 while (x > 0) {
1472 x >>= 1;
1473 d++;
1474 }
1475 return d;
1476 }
1477
1478
1479 2.返回x的二进制表示中从低到高的第i位
1480 语法:result=BitAt(int x, int i);
1481 参数:
1482 x:十进制 x
1483 i:要求二进制的第i位
1484 返回值:返回x的二进制表示中从低到高的第i位
1485 注意:
1486 最低位为第一位
1487 源程序:
1488 int BitAt(int x, int i)
1489 {
1490 return ( x & (1 << (i-1)) );
1491 }
1492
1493
1494 3.模取幂运算
1495 语法:result=Modular_Expoent(int a,int b,int n);
1496 参数:
1497 a、b、n:a^b mod n 的对应参数
1498 返回值:a^b mod n 的值
1499 注意:
1500 需要BitLength和BitAt
1501 源程序:
1502 int Modular_Expoent(int a,int b,int n)
1503 {
1504 int i, y=1;
1505 for (i = BitLength(b); i > 0; i--)
1506 {
1507 y = (y*y)%n;
1508 if (BitAt(b,i) > 0)
1509 y = (y*a)%n;
1510 }
1511 return y;
1512 }
1513
1514
1515 4.求解模线性方程
1516 语法:result=modular_equation(int a,int b,int n);
1517 参数:
1518 a、b、n:ax=b (mod n) 的对应参数
1519 返回值:方程的解
1520 源程序:
1521 int ext_euclid(int a,int b,int &x,int &y) //求gcd(a,b)=ax+by
1522 {
1523 int t,d;
1524 if (b==0) {x=1;y=0;return a;}
1525 d=ext_euclid(b,a %b,x,y);
1526 t=x;
1527 x=y;
1528 y=t-a/b*y;
1529 return d;
1530 }
1531
1532 void modular_equation(int a,int b,int n)
1533 {
1534 int e,i,d;
1535 int x,y;
1536 d=ext_euclid(a,n,x,y);
1537 if (b%d>0)
1538 printf("No answer!\n");
1539 else
1540 {
1541 e=(x*(b/d))%n;
1542 for (i=0;i<d;i++)
1543 printf("The %dth answer is : %ld\n",i+1,(e+i*(n/d))%n);
1544 }
1545 }
1546
1547
1548 5.求解模线性方程组(中国余数定理)
1549 语法:result=Modular_Expoent(int a,int b,int n);
1550 参数:
1551 B[]、W[]:a=B[] (mod W[]) 的对应参数
1552 返回值:a 的值
1553 注意:
1554 其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a
1555 源程序:
1556 int ext_euclid(int a,int b,int &x,int &y) //求gcd(a,b)=ax+by
1557 {
1558 int t,d;
1559 if (b==0) {x=1;y=0;return a;}
1560 d=ext_euclid(b,a %b,x,y);
1561 t=x;
1562 x=y;
1563 y=t-a/b*y;
1564 return d;
1565 }
1566
1567
1568 int China(int B[],int W[],int k)
1569 {
1570 int i;
1571 int d,x,y,a=0,m,n=1;
1572 for (i=0;i<k;i++)
1573 n*=W[i];
1574 for (i=0;i<k;i++)
1575 {
1576 m=n/W[i];
1577 d=ext_euclid(W[i],m,x,y);
1578 a=(a+y*m*B[i])%n;
1579 }
1580 if (a>0) return a;
1581 else return(a+n);
1582 }
1583
1584
1585 6.筛法素数产生器
1586 语法:result=prime(int a[],int n);
1587 参数:
1588 a[]:用于返回素数的数组
1589 n:产生n以内的素数,按升序放入a[]中
1590 返回值:n以内素数的个数
1591 注意:
1592 其中W[],B[]已知,W[i]>0且W[i]与W[j]互质, 求a
1593 源程序:
1594 int prime(int a[],int n)
1595 {
1596 int i,j,k,x,num,*b;
1597 n++;
1598 n/=2;
1599 b=new int[(n+1)*2];
1600 a[0]=2;a[1]=3;num=2;
1601 for(i=1;i<=2*n;i++)
1602 b[i]=0;
1603 for(i=3;i<=n;i+=3)
1604 for(j=0;j<2;j++)
1605 {
1606 x=2*(i+j)-1;
1607 while(b[x]==0)
1608 {
1609 a[num++]=x;
1610 for(k=x;k<=2*n;k+=x)
1611 b[k]=1;
1612 }
1613 }
1614 return num;
1615 }
1616
1617
1618 7.判断一个数是否素数
1619 语法:result=comp(int n);
1620 参数:
1621 n:判断n是否素数
1622 返回值:素数返回1,否则返回0
1623 源程序:
1624 //传统方法
1625 int comp(int n){
1626 if(n<2)return 0;
1627 if(n%2==0)return 0;
1628 for(int i=3;i<=sqrt(n);i+=2) if(n%i==0) return 0;
1629 return 1;
1630 }
1631
1632 //大数素数判定,(1/4)^K出错概率
1633 int powermod(int a,int b,int n)
1634 {//get (a^b)%n
1635 i64 d=1, t=a;
1636 while(b>0){
1637 if(t==1)return d;
1638 if(b%2==1)d=(t*d)%n;
1639 b/=2; t=(t*t)%n;
1640 }
1641 return d;
1642 }
1643 int isprime(int n,int k){
1644 int a;
1645 while(k--){
1646 a=rand();
1647 a%=n-3; a+=2;
1648 if(powermod(k+2,n-1,n)!=1)return 0;
1649 }
1650 return 1;
1651 }
1652
1653
1654 8.求距阵最大和
1655 语法:result=maxsum2(int n);
1656 参数:
1657 a:距阵
1658 n,m:距阵行列数
1659 返回值:一维,二维距阵最大和
1660 源程序:
1661 int a[101][101];
1662 int maxsum(int a[],int n)//一维最大串
1663 {
1664 int sum=-10000000,b=0;
1665 int i;
1666 for(i=0;i<n;i++)
1667 {
1668 if (b>0)
1669 b+=a[i];
1670 else
1671 b=a[i];
1672 if(b>sum)
1673 sum=b;
1674 }
1675 return sum;
1676 }
1677 int maxsum2(int m,int n)//二维最大串
1678 {
1679 int sum = -10000000;
1680 int i,j,k,max;
1681 int* b = new int[n+1];
1682 for (i=0;i<m;i++)
1683 {
1684 for(k=0;k<n;k++)
1685 b[k]=a[i][k];
1686 max = maxsum(b,n);//第i列的一维最大串
1687 if(max>sum)
1688 sum=max;
1689 for(j=i+1;j<m;j++)
1690 {
1691 for (k=0;k<=n;k++)b[k]+=a[j][k];
1692 max = maxsum(b,n);//类似maxsum,通过每列相加求二维最大串
1693 if(max>sum)sum=max;
1694 }
1695 }
1696 delete []b;
1697 return sum;
1698 }
1699
1700
1701 8.求一个数每一位相加之和
1702 语法:result=digadd(int n)
1703 参数:
1704 n:待求数字
1705 返回值:各数字之和
1706 源程序:
1707 int digadd(int n)
1708 {
1709 int i=0,k=0;
1710 while(i=n%10,n/=10) k+=i;
1711 return k+i;
1712 }
1713
1714
1715 10.质因数分解
1716 语法:result=int reduce(int prime[],int pn,int n,int rest[])
1717 参数:
1718 Prime[]:素数表,至少需要达到sqrt(n)
1719 pn:素数表的元素个数
1720 N:待分解的数
1721 Rest:分解结果,按照升序排列
1722 返回值:分解因子个数
1723 源程序:
1724 int reduce(int prime[],int pn,int n,int rest[])
1725 {
1726 int i,k=0;
1727 for(i=0;i<pn;i++)
1728 {
1729 if (n==1) break;
1730 if (prime[i]*prime[i]>n) {rest[k++]=n;break;}
1731 while(n%prime[i]==0)
1732 {
1733 n/=prime[i];
1734 rest[k++]=prime[i];
1735 }
1736 }
1737 return k;
1738 }
1739
1740
1741 11.高斯消元法解线性方程组
1742 语法:gauss(int n,double ** a)
1743 参数:
1744 N:变量个数
1745 Rest:变量系数行列式
1746 源程序:
1747 void gauss(int n,double **a)
1748 {
1749 int i, j, k;
1750 double client, temp = 0.0;
1751
1752 for(k = 0; k < n - 1; k++)
1753 for(i = k + 1; i < n; i++)
1754 {
1755 client = a[i][k]/a[k][k];
1756 for(j = k + 1; j < n; j++)
1757 a[i][j] = a[i][j] - client * a[k][j];
1758 a[i][n] = a[j - 1][n] - client * a[k][n];
1759 }
1760 a[n - 1][n] = a[n - 1][n]/a[n - 1][n - 1];
1761 for(i = n - 2; i >= 0; i--)
1762 {
1763 for (j = i + 1; j < n; j++)
1764 temp += a[i][j] * a[j][n];
1765 a[i][n] = (a[i][n] - temp) / a[i][i];
1766 }
1767 }
1768
1769 //打印
1770 //for(i = 0; i < n; i++)
1771 // printf("X%d = %lf\n", i + 1, a[i][n]);
1772
1773
1774 五、图论
1775 1.Prim算法求最小生成树
1776 语法:prim(Graph G,int vcount,int father[]);
1777 参数:
1778 G:图,用邻接矩阵表示
1779 vcount:表示图的顶点个数
1780 father[]:用来记录每个节点的父节点
1781 返回值:null
1782 注意:
1783 常数max_vertexes为图最大节点数
1784 常数infinity为无穷大
1785 源程序:
1786 #define infinity 1000000
1787 #define max_vertexes 5
1788
1789 typedef int Graph[max_vertexes][max_vertexes];
1790
1791 void prim(Graph G,int vcount,int father[])
1792 {
1793 int i,j,k;
1794 int lowcost[max_vertexes],closeset[max_vertexes],used[max_vertexes];
1795 for (i=0;i<vcount;i++)
1796 {
1797 lowcost[i]=G[0][i];
1798 closeset[i]=0;
1799 used[i]=0;
1800 father[i]=-1;
1801 }
1802 used[0]=1;
1803 for (i=1;i<vcount;i++)
1804 {
1805 j=0;
1806 while (used[j]) j++;
1807 for (k=0;k<vcount;k++)
1808 if ((!used[k])&&(lowcost[k]<lowcost[j])) j=k;
1809 father[j]=closeset[j];
1810 used[j]=1;
1811 for (k=0;k<vcount;k++)
1812 if (!used[k]&&(G[j][k]<lowcost[k]))
1813 { lowcost[k]=G[j][k];
1814 closeset[k]=j; }
1815 }
1816 }
1817
1818
1819 2.Dijkstra算法求单源最短路径
1820 语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);
1821 参数:
1822 G:图,用邻接矩阵表示
1823 n:图的顶点个数
1824 s:开始节点
1825 t:目标节点
1826 path[]:用于返回由开始节点到目标节点的路径
1827 返回值:最短路径长度
1828 注意:
1829 输入的图的权必须非负
1830 顶点标号从0开始
1831 用如下方法打印路径:
1832 i=t;
1833 while (i!=s)
1834 {
1835 printf("%d<--",i+1);
1836 i=path[i];
1837 }
1838 printf("%d\n",s+1);
1839 源程序:
1840 int Dijkstra(Graph G,int n,int s,int t, int path[])
1841 {
1842 int i,j,w,minc,d[max_vertexes],mark[max_vertexes];
1843 for (i=0;i<n;i++) mark[i]=0;
1844 for (i=0;i<n;i++)
1845 { d[i]=G[s][i];
1846 path[i]=s; }
1847 mark[s]=1;path[s]=0;d[s]=0;
1848 for (i=1;i<n;i++)
1849 {
1850 minc=infinity;
1851 w=0;
1852 for (j=0;j<n;j++)
1853 if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}
1854 mark[w]=1;
1855 for (j=0;j<n;j++)
1856 if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))
1857 { d[j]=d[w]+G[w][j];
1858 path[j]=w; }
1859 }
1860 return d[t];
1861 }
1862
1863
1864 3.Bellman-ford算法求单源最短路径
1865 语法:result=Bellman_ford(Graph G,int n,int s,int t,int path[],int success);
1866 参数:
1867 G:图,用邻接矩阵表示
1868 n:图的顶点个数
1869 s:开始节点
1870 t:目标节点
1871 path[]:用于返回由开始节点到目标节点的路径
1872 success:函数是否执行成功
1873 返回值:最短路径长度
1874 注意:
1875 输入的图的权可以为负,如果存在一个从源点可达的权为负的回路则success=0
1876 顶点标号从0开始
1877 用如下方法打印路径:
1878 i=t;
1879 while (i!=s)
1880 {
1881 printf("%d<--",i+1);
1882 i=path[i];
1883 }
1884 printf("%d\n",s+1);
1885 源程序:
1886 int Bellman_ford(Graph G,int n,int s,int t,int path[],int success)
1887 {
1888 int i,j,k,d[max_vertexes];
1889 for (i=0;i<n;i++) {d[i]=infinity;path[i]=0;}
1890 d[s]=0;
1891 for (k=1;k<n;k++)
1892 for (i=0;i<n;i++)
1893 for (j=0;j<n;j++)
1894 if (d[j]>d[i]+G[i][j]) {d[j]=d[i]+G[i][j];path[j]=i;}
1895 success=0;
1896 for (i=0;i<n;i++)
1897 for (j=0;j<n;j++)
1898 if (d[j]>d[i]+G[i][j]) return 0;
1899 success=1;
1900 return d[t];
1901 }
1902
1903
1904 4.Floyd-Warshall算法求每对节点间最短路径
1905 语法:Floyd_Washall(Graph G,int n,Graph D,Graph P);
1906 参数:
1907 G:图,用邻接矩阵表示
1908 n:图的顶点个数
1909 D:D[i,j]表示从i到j的最短距离
1910 P:P[i,j]表示从i到j的最短路径上j 的父节点
1911 自定义:MaxN;
1912 返回值:null
1913 注意:此算法允许图中带有负权的弧,但不允许有路径长度为负值的回路.
1914 源程序:
1915 void Floyd(int G[][MaxN],int n,int D[][MaxN],int P[][MaxN])
1916 {
1917 int i,j,k;
1918 for (i=0;i<n;i++)
1919 for (j=0;j<n;j++)
1920 { D[i][j]=G[i][j];
1921 P[i][j]=i; }
1922 for (i=0;i<n;i++) { D[i][i]=0;P[i][i]=0; }
1923 for (k=0;k<n;k++)
1924 for (i=0;i<n;i++)
1925 for (j=0;j<n;j++)
1926 if (D[i][j]>D[i][k]+D[k][j])
1927 { D[i][j]=D[i][k]+D[k][j];
1928 P[i][j]=P[k][j]; }
1929 }
1930 void Floyd(int n,int D[][MaxN]) //G不用再输出的情况下.
1931 {
1932 int i,j,k;
1933 for (i=0;i<n;i++) { D[i][i]=0; }
1934 for (k=0;k<n;k++)
1935 for (i=0;i<n;i++)
1936 for (j=0;j<n;j++)
1937 if (D[i][j]>D[i][k]+D[k][j])
1938 { D[i][j]=D[i][k]+D[k][j];
1939 }
1940 }
1941
1942 5.解欧拉图
1943 语法:int Eular(int graph[8][8], int v, int *path)
1944 参数:
1945 graph:图,用邻接矩阵表示
1946 v:图的顶点个数
1947 path:D[i,j]表示从i到j的最短距离
1948 注意:
1949 此函数会删除图中的边
1950 返回值:若找到欧拉回路则返回路径长度,否则返回-1
1951 源程序:
1952 int Eular(int graph[8][8], int v, int *path)
1953 {
1954 int start,a,b,count=0, deg,i;
1955 int s[1000], sp=0;//栈,大小可根据需要改变
1956
1957 start=0;
1958 while(true)
1959 {
1960 a=start;
1961 s[sp++]=a;
1962 for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}
1963 for(;b!=start&&b!=-1;)
1964 {
1965 s[sp++]=b;
1966 graph[a][b]=graph[b][a]=0;
1967 a=b;
1968 for(b=-1,i=0;i<v;i++) if (graph[i][a]&& a!=i) {b=i;break;}
1969 }
1970 if (b==-1) return(-1);//若找不到Eular回路返回-1
1971 s[sp++]=b;
1972 graph[a][b]=graph[b][a]=0;
1973
1974 while(sp>0)
1975 {
1976 b=s[--sp];
1977 for(i=0,deg=0;i<v;i++) if (graph[i][b]==1) {deg++; break;}
1978 if (deg>0) break;
1979 path[count++]=b;
1980 }
1981 if (sp==0) return(count);
1982 start=b;
1983 }
1984
1985 }
1986
1987
1988 六、排序/查找
1989 1.快速排序
1990 语法:quicksort(int l,int r,int b[]);
1991 参数:
1992 l:排序上界,开始时l=0
1993 r:排序下界,开始时r=数组元素个数
1994 b[]:被排序的元素
1995 返回值:null
1996 注意:
1997 输出升序序列
1998 源程序:
1999 void quicksort(int l,int r,int b[])
2000 {
2001 int i,j,x;
2002 if(l>=r) return;
2003 i=l;
2004 j=r;
2005 x=b[i];
2006 while(i!=j)
2007 {
2008 while(b[j]>x&&j>i) j--;
2009 if(i<j)
2010 {
2011 b[i]=b[j];
2012 i++;
2013 }
2014 while(b[i]<x&&j>i)i++;
2015 if(i<j)
2016 {
2017 b[j]=b[i];
2018 j--;
2019 }
2020 }
2021 b[i]=x;
2022 quicksort(l,j-1,b);
2023 quicksort(i+1,r,b);
2024 }
2025
2026
2027 2.希尔排序
2028 语法:shellsort(int a[],int n);
2029 参数:
2030 n:数组元素个数
2031 a[]:待排序数组
2032 返回值:null
2033 注意:
2034 输出升序序列
2035 源程序:
2036 void shellsort(int a[],int n)
2037 {
2038 int i,j,g;
2039 int temp,k;
2040 g=n/2;
2041 while(g!=0)
2042 {
2043 for(i=g+1;i<=n;i++)
2044 {
2045 temp=a[i];
2046 j=i-g;
2047 while(j>0)
2048 {
2049 k=j+g;
2050 if(a[j]<=a[k])
2051 j=0;
2052 else
2053 {
2054 temp=a[j];a[j]=a[k];a[k]=temp;
2055 }
2056 j=j-g;
2057 }
2058 }
2059 g=g/2;
2060 }
2061 }
2062
2063
2064 3.选择法排序
2065 语法:sort(int t[],int n);
2066 参数:
2067 t[]:待排序数组
2068 n:数组t[]元素的个数
2069 返回值:null
2070 注意:
2071 输出升序序列
2072 小规模排序用
2073 源程序:
2074 void sort(int t[],int n)
2075 {
2076 int i,j,k,temp;
2077 for (i=0;i<n;i++)
2078 {
2079 k=i;
2080 for (j=i;j<n;j++) if (t[j]<t[k]) k=j;
2081 temp=t[i];t[i]=t[k];t[k]=temp;
2082 }
2083 }
2084
2085
2086 4.二分查找
2087 语法:result=search_bin(int *t,int k);
2088 参数:
2089 t[]:待查找数组
2090 k:查找关键字
2091 返回值:如果k在t[]中存在,输出i:t[i]=k,否则输出-1
2092 注意:
2093 要求查找数组是有序升序序列
2094 源程序:
2095 int search_bin(int *t,int k)
2096 {
2097 int low=1,high=10,mid;
2098 while (low<=high)
2099 {
2100 mid=(low+high)/2;
2101 if (k==t[mid]) return mid;
2102 else if (k<t[mid]) high=mid-1;
2103 else low=mid+1;
2104 }
2105 return -1;
2106 }
2107
2108
2109 七、数据结构
2110 1.顺序队列
2111 源程序:
2112 #define maxsize 100
2113 typedef struct
2114 {
2115 int data[maxsize];
2116 int front;
2117 int rear;
2118 } sqqueue;
2119 int sqinit(sqqueue *p) //队列初始化
2120 {
2121 p->front=0;
2122 p->rear=0;
2123 return 1;
2124 }
2125 int enqueue(sqqueue *q, int e) //入队
2126 {
2127 if((q->rear+1)%maxsize==q->front)
2128 return 0;
2129 else
2130 q->data[q->rear]=e;
2131 q->rear=(q->rear+1)%maxsize;
2132 return 1;
2133 }
2134 int dequeue(sqqueue *q) //出队
2135 {
2136 int e;
2137 if (q->front==q->rear)
2138 return 0;
2139 e=q->data[q->front];
2140 q->front=(q->front+1)%maxsize;
2141 return e;
2142 }
2143 int empty(sqqueue *q) //判空
2144 {
2145 int v;
2146 if (q->front==q->rear)
2147 v=1;
2148 else
2149 v=0;
2150 return v;
2151 }
2152 int gethead(sqqueue *q) //取得头元素
2153 {
2154 int e;
2155 if (q->front==q->rear)
2156 e=-1;
2157 else
2158 e=q->data[q->front];
2159 return e;
2160 }
2161 void display(sqqueue *q) //显示所有元素
2162 {
2163 int s;
2164 s=q->front;
2165 printf("the sequeue is display:\n");
2166 if (q->front==q->rear)
2167 printf("the sequeue is empty!");
2168 else
2169 {
2170 while(s<q->rear)
2171 {
2172 printf("->%d", q->data[s]);
2173 s=(s+1)%maxsize;
2174 }
2175 printf("\n");
2176 }
2177 }
2178 main(sqqueue *head) //函数使用样例
2179 {
2180 int n,i,m,x,y,select,xq;
2181 printf("create a empty sequeue\n");
2182 sqinit(head);
2183 printf("please input the sequeue length:\n");
2184 scanf("%d",&n);
2185 for (i=0;i<n;i++)
2186 {
2187 printf("please input a sequeue value:\n");
2188 scanf("%d",&m);
2189 enqueue(head,m);
2190 }
2191 printf("head->rear:%d\n",head->rear);
2192 printf("head->front:%d\n",head->front);
2193 display(head);
2194 printf("select 1 **** enqueue() \n");
2195 printf("select 2 **** dequeue() \n");
2196 printf("select 3 **** empty () \n");
2197 printf("select 4 **** gethead() \n");
2198 printf("select 5 **** display() \n");
2199 printf("please select (1--5):");
2200 scanf("%d",&select);
2201 switch(select)
2202 {
2203 case 1:
2204 {
2205 printf("please input a value :\n ");
2206 scanf("%d",&x);
2207 enqueue(head,x);
2208 display(head);
2209 break;
2210 }
2211 case 2:
2212 {
2213 dequeue(head);
2214 display(head);
2215 break;
2216 }
2217 case 3:
2218 {
2219 if(empty(head))
2220 printf("the sequeue is empty");
2221 else
2222 printf("the sequeue is full");
2223 }
2224 case 4:
2225 {
2226 y=gethead(head);
2227 printf("output head value:%d\n",y);
2228 break;
2229 }
2230 case 5:
2231 {
2232 display(head);
2233 break;
2234 }
2235 }
2236 }
2237 }
2238
2239
2240 2.顺序栈
2241 源程序:
2242 #define m 100
2243 typedef struct
2244 {
2245 int stack[m];
2246 int top;
2247 } stackstru;
2248 init(stackstru *s) /*装入栈*/
2249 {
2250 s->top=0;
2251 return 1;
2252 }
2253 int push(stackstru *s,int x) /*入栈操作*/
2254 {
2255 if (s->top==m)
2256 printf("the stack is overflow!\n");
2257 else
2258 {
2259 s->top=s->top+1;
2260 s->stack[s->top]=x;
2261 }
2262 }
2263 void display(stackstru *s) /*显示栈所有数据*/
2264 {
2265 if(s->top==0)
2266 printf("the stack is empty!\n");
2267 else
2268 {
2269 while(s->top!=0)
2270 {
2271 printf("%d->",s->stack[s->top]);
2272 s->top=s->top-1;
2273 }
2274 }
2275 }
2276 int pop(stackstru *s) /*出栈操作并返回被删除的那个记录*/
2277 {
2278 int y;
2279 if(s->top==0)
2280 printf("the stack is empty!\n");
2281 else
2282 {
2283 y=s->stack[s->top];
2284 s->top=s->top-1;
2285 return y;
2286 }
2287 }
2288
2289 int gettop(stackstru *s) /*得到栈顶数*/
2290 {
2291 int e;
2292 if(s->top==0)
2293 return 0;
2294 else
2295 e=s->stack[s->top];
2296 return e;
2297 }
2298 main(stackstru *p) //函数使用演示
2299 {
2300 int n,i,k,h,x1,x2,select;
2301 printf("create a empty stack!\n");
2302 init(p);
2303 printf("input a stack length:\n");
2304 scanf("%d",&n);
2305 for(i=0;i<n;i++)
2306 {
2307 printf("input a stack value:\n");
2308 scanf("%d",&k);
2309 push(p,k);
2310 }
2311 printf("select 1:display()\n");
2312 printf("select 2:push()\n");
2313 printf("select 3:pop()\n");
2314 printf("select 4:gettop()\n");
2315 printf("input a your select(1-4):\n");
2316 scanf("%d",&select);
2317 switch(select)
2318 {
2319 case 1:
2320 {
2321 display(p);
2322 break;
2323 }
2324 case 2:
2325 {
2326 printf("input a push a value:\n");
2327 scanf("%d",&h);
2328 push(p,h);
2329 display(p);
2330 break;
2331 }
2332 case 3:
2333 {
2334 x1=pop(p);
2335 printf("x1->%d\n",x1);
2336 display(p);
2337 break;
2338 }
2339 case 4:
2340 {
2341 x2=gettop(p);
2342 printf("x2->%d",x2);
2343 break;
2344 }
2345 }
2346 }
2347
2348
2349 3.链表
2350 源程序:
2351 # define null 0
2352
2353 typedef char ElemType; /* 字符型数据*/
2354
2355 typedef struct LNode
2356 {
2357 ElemType data;
2358 struct LNode *next;
2359 };
2360
2361 setnull(struct LNode **p);
2362 int length (struct LNode **p);
2363 ElemType get(struct LNode **p,int i);
2364 void insert(struct LNode **p,ElemType x,int i);
2365 int delete(struct LNode **p,int i);
2366 void display(struct LNode **p);
2367 main()
2368 {
2369 struct LNode *head,*q; /*定义静态变量*/
2370 int select,x1,x2,x3,x4;
2371 int i,n;
2372 int m,g;
2373 char e,y;
2374
2375 head=setnull(&head); /*建议链表并设置为空表*/
2376 printf("请输入数据长度: ");
2377 scanf("%d",&n);
2378 for(i=1;i<n;i++);
2379 {
2380 printf("将数据插入到单链表中: ");
2381 scanf("%d",&y);
2382 insert(&head,y,i);} /*插入数据到链表*/
2383 display(&head); /*显示链表所有数据*/
2384
2385 printf("select 1 求长度 length()\n");
2386 printf("select 2 取结点 get()\n");
2387 printf("select 3 求值查找 locate()\n");
2388 printf("select 4 删除结点 delete()\n");
2389 printf("input your select: ");
2390 scanf("%d",&select);
2391 switch(select)
2392 {
2393 case 1:
2394 {
2395 x1=length(&head);
2396 printf("输出单链表的长度%d ",x1);
2397 display(&head);
2398 }break;
2399 case 2:
2400 {
2401 printf("请输入要取得结点: ");
2402 scanf("%d",&m);
2403 x2=get(&head,m);
2404 printf(x2);
2405 display(&head);
2406 }break;
2407 case 3:
2408 {
2409 printf("请输入要查找的数据: ");
2410 scanf("%d",&e);
2411 x3=locate(&head,e);
2412 printf(x3);
2413 display(&head);
2414 }break;
2415 case 4:
2416 {
2417 printf("请输入要删除的结点: ");
2418 scanf("%d",&g);
2419 x4=delete(&head,g);
2420 printf(x4);
2421 display(&head);
2422 }break;
2423 }
2424 }
2425 }
2426
2427 setnull(struct LNode **p)
2428 {
2429 *p=null;
2430 }
2431 int length (struct LNode **p)
2432 {
2433 int n=0;
2434 struct LNode *q=*p;
2435 while (q!=null)
2436 {
2437 n++;
2438 q=q->next;
2439 }
2440 return(n);
2441 }
2442 ElemType get(struct LNode **p,int i)
2443 {
2444 int j=1;
2445 struct LNode *q=*p;
2446 while (j<i&&q!=null)
2447 {
2448 q=q->next;
2449 j++;
2450 }
2451 if(q!=null)
2452 return(q->data);
2453 else
2454 printf("位置参数不正确!\n");
2455 }
2456 int locate(struct LNode **p,ElemType x)
2457 {
2458 int n=0;
2459 struct LNode *q=*p;
2460 while (q!=null&&q->data!=x)
2461 {
2462 q=q->next;
2463 n++;
2464 }
2465 if(q==null)
2466 return(-1);
2467 else
2468 return(n+1);
2469 }
2470 void insert(struct LNode **p,ElemType x,int i)
2471 {
2472 int j=1;
2473 struct LNode *s,*q;
2474 s=(struct LNode *)malloc(sizeof(struct LNode));
2475 s->data=x;
2476 q=*p;
2477 if(i==1)
2478 {
2479 s->next=q;
2480 p=s;
2481 }
2482 else
2483 {
2484 while(j<i-1&&q->next!=null)
2485 {
2486 q=q->next;
2487 j++;
2488 }
2489 if(j==i-1)
2490 {
2491 s->next=q->next;
2492 q->next=s;
2493 }
2494 else
2495 printf("位置参数不正确!\n");
2496 }
2497 }
2498 int delete(struct LNode **p,int i)
2499 {
2500 int j=1;
2501 struct LNode *q=*p,*t;
2502 if(i==1)
2503 {
2504 t=q;
2505 *p=q->next;
2506 }
2507 else
2508 {
2509 while(j<i-1&&q->next!=null)
2510 {
2511 q=q->next;
2512 j++;
2513 }
2514 if(q->next!=null&&j==i-1)
2515 {
2516 t=q->next;
2517 q->next=t->next;
2518 }
2519 else
2520 printf("位置参数不正确!\n");
2521 }
2522 if(t=null)
2523 free(t);
2524 }
2525 void display(struct LNode **p)
2526 {
2527 struct LNode *q;
2528 q=*p;
2529 printf("单链表显示: ");
2530 if(q==null)
2531 printf("链表为空!");
2532 else if (q->next==null)
2533 printf("%c\n",q->data);
2534 else
2535 {
2536 while(q->next!=null)
2537 {
2538 printf("%c->",q->data);
2539 q=q->next;
2540 }
2541 printf("%c",q->data);
2542 }
2543 printf("\n");
2544 }
2545
2546
2547 4.链栈
2548 源程序:
2549 # define null 0
2550
2551 typedef struct stacknode
2552 {
2553 int data;
2554 struct stacknode *next;
2555 } stacklink;
2556 typedef struct
2557 {
2558 stacklink *top;
2559 int stacksize;
2560 }stackk;
2561
2562 initlink(stackk *s)
2563 {
2564 s->top=(stacklink *)malloc(sizeof(stacklink));
2565 s->top->data=0;
2566 s->top->next=null;
2567 }
2568
2569 int poplink(stackk *s)
2570 {
2571 stackk *p;int v;
2572 if(s->top->next==null) printf("the stackis empty\n");
2573 else
2574 {
2575 v=s->top->next->data;
2576 p=s->top->next;
2577 s->top=s->top->next;
2578 }
2579 free(p);
2580 return v;
2581 }
2582 }
2583 int pushlink(stackk *s,int x)
2584 {
2585 stackk *p;
2586 p=(stacklink *)malloc(sizeof(stacklink));
2587 p->data=x;
2588 p->next=s->top->next;
2589 s->top->next=p;
2590 }
2591 int gettop(stackk *s)
2592 {
2593 int e;
2594 if(s==null) printf("the stack is empty!\n");
2595 e=s->top->next->data;
2596 return e;
2597 }
2598
2599 display(stackk *s)
2600 {
2601 stackk *p;
2602 p=s->top->next;
2603 printf("display the stacklink:\n");
2604 if (s->top=null) printf("the stacklink is empty!\n");
2605 else
2606 {
2607 while(p)
2608 {
2609 printf("->%d",p->data);
2610 p=p->next;
2611 }
2612 }
2613 }
2614
2615 main(stacklink *p)
2616 {
2617 int n,k,i,select,h,x1,x2;
2618 printf("create a empty stacklink!\n");
2619 initlink(p);
2620 printf("input a stacklink length:\n");
2621 scanf("%d",&n);
2622 for (i=1;i<=n;i++)
2623 {printf("input a stacklink value:\n");
2624 scanf("%d",&k);
2625 pushlink(p,k);
2626 }
2627 printf("select 1:display()\n");
2628 printf("select 2:pushlink()\n");
2629 printf("select 3:poplink()\n");
2630 printf("select 4:gettop()\n");
2631 printf("input a your select(1-4):\n");
2632 scanf("%d",&select);
2633 switch(select)
2634 {case 1:
2635 {display(p);break;}
2636 case 2:
2637 {printf("input a push a value :\n");
2638 scanf("%d",&h);
2639 pushlink(p,h);
2640 display(p);
2641 break;}
2642 case 3:
2643 {x1=poplink(p);printf("x1->%d\n",x1);
2644 display(p);
2645 break;}
2646 case 4:
2647 {x2=gettop(p);printf("x2->%d",x2);
2648 break;}
2649 }
2650 }
2651
2652
2653 5.二叉树
2654 源程序:
2655 typedef struct bitnode
2656 {
2657 char data;
2658 struct bitnode *lchild, *rchild;
2659 }bitnode, *bitree;
2660 void createbitree(t,n)
2661 bitnode ** t;
2662 int *n;
2663 {
2664 char x;
2665 bitnode *q;
2666 *n=*n+1;
2667 printf("\n Input %d DATA:",*n);
2668 x=getchar();
2669 if(x!='\n') getchar();
2670 if (x=='\n')
2671 return;
2672 q=(bitnode*)malloc(sizeof(bitnode));
2673 q->data=x;
2674 q->lchild=NULL;
2675 q->rchild=NULL;
2676 *t=q;
2677 printf(" This Address is: %o, Data is: %c,\n Left Pointer is: %o,
2678 Right Pointer is: %o",q,q->data,q->lchild,q->rchild);
2679 createbitree(&q->lchild,n);
2680 createbitree(&q->rchild,n);
2681 return;
2682 }
2683
2684 void visit(e)
2685 bitnode *e;
2686 {
2687 printf(" Address: %o, Data: %c, Left Pointer: %o, Right Pointer:
2688 %o\n",e,e->data,e->lchild,e->rchild);
2689 }
2690
2691 void preordertraverse(t)
2692 bitnode *t;
2693 {
2694 if(t)
2695 {
2696 visit(t);
2697 preordertraverse(t->lchild);
2698 preordertraverse(t->rchild);
2699 return ;
2700 }
2701 else
2702 return ;
2703 }
2704 void countleaf(t,c)
2705 bitnode *t;
2706 int *c;
2707 {
2708 if(t!=NULL)
2709 {
2710 if (t->lchild==NULL && t->rchild==NULL)
2711 {*c=*c+1;
2712 }
2713 countleaf(t->lchild,c);
2714 countleaf(t->rchild,c);
2715 }
2716 return;
2717 }
2718 int treehigh(t)
2719 bitnode *t;
2720 {
2721 int lh,rh,h;
2722 if(t==NULL)
2723 h=0;
2724 else
2725 {
2726 lh=treehigh(t->lchild);
2727 rh=treehigh(t->rchild);
2728 h=(lh>rh ? lh:rh)+1;
2729 }
2730 return h;
2731 }
2732
2733 main()
2734 {
2735 bitnode *t; int count=0;
2736 int n=0;
2737 printf("\n Please input TREE Data:\n");
2738 createbitree(&t,&n);
2739 printf("\n This is TREE struct: \n");
2740 preordertraverse(t);
2741 countleaf(t,&count);
2742 printf("\n This TREE has %d leaves ",count);
2743 printf(" , High of The TREE is: %d\n",treehigh(t));
2744 }
2745
2746
2747 八、高精度运算专题
2748 1.专题函数说明
2749 说明:
2750 本栏为本专题所有程序的公用部分,调用本专题任何一个程序必须加上本栏的代码
2751 input/print为高精度数输入输出,调用格式为input(hp HightPoint,"123456")/print(hp
2752 HighPoint)
2753 本栏为纯C++代码
2754 源程序:
2755 #include <iostream>
2756 using namespace std;
2757 #define maxsize 100
2758 struct hp
2759 {
2760 int len;
2761 int s[maxsize+1];
2762 };
2763
2764 void input(hp &a,string str)
2765 {
2766 int i;
2767 while(str[0]=='0' && str.size()!=1)
2768 str.erase(0,1);
2769 a.len=(int)str.size();
2770 for(i=1;i<=a.len;++i)
2771 a.s[i]=str[a.len-i]-48;
2772 for (i=a.len+1;i<=maxsize;++i)
2773 a.s[i]=0;
2774 }
2775 void print(const hp &y)
2776 {
2777 int i;
2778 for(i=y.len;i>=1;i--)
2779 cout<<y.s[i];
2780 cout<<endl;
2781 }
2782
2783
2784 2.高精度数比较
2785 语法:int result=compare(const hp &a,const hp &b);
2786 参数:
2787 a,b:进行比较的高精度数字
2788 返回值:比较结果,a>b返回正数,a=b返回0,a<b返回负数
2789 源程序:
2790 int compare(const hp &a,const hp &b)
2791 {
2792 int len;
2793 if(a.len>b.len)
2794 len=a.len;
2795 else
2796 len=b.len;
2797 while(len>0 && a.s[len]==b.s[len]) len--;
2798 if(len==0)
2799 return 0;
2800 else
2801 return a.s[len]-b.s[len];
2802 }
2803
2804
2805 3.高精度数加法
2806 语法:plus(const hp &a,const hp &b,hp &c);
2807 参数:
2808 a,b:进行加法的高精度数字
2809 返回值:返回相加结果到c中
2810 源程序:
2811 void plus(const hp &a,const hp &b,hp &c)
2812 {
2813 int i,len;
2814 for(i=1;i<=maxsize;i++) c.s[i]=0;
2815 if(a.len>b.len) len=a.len;
2816 else len=b.len;
2817 for(i=1;i<=len;i++)
2818 {
2819 c.s[i]+=a.s[i]+b.s[i];
2820 if(c.s[i]>=10)
2821 {
2822 c.s[i]-=10;
2823 c.s[i+1]++;
2824 }
2825 }
2826 if(c.s[len+1]>0) len++;
2827 c.len=len;
2828 }
2829
2830
2831 4.高精度数减法
2832 语法:subtract(const hp &a,const hp &b,hp &c);
2833 参数:
2834 a,b:进行减法的高精度数字,a是被减数,b是减数,不支持负数
2835 返回值:返回结果到c中
2836 源程序:
2837 void subtract(const hp &a,const hp &b,hp &c)
2838 {
2839 int i,len;
2840 for(i=1;i<=maxsize;i++) c.s[i]=0;
2841 if(a.len>b.len) len=a.len;
2842 else len=b.len;
2843 for(i=1;i<=len;i++)
2844 {
2845 c.s[i]+=a.s[i]-b.s[i];
2846 if(c.s[i]<0)
2847 {
2848 c.s[i]+=10;
2849 c.s[i+1]--;
2850 }
2851 }
2852 while(len>1&&c.s[len]==0) len--;
2853 c.len=len;
2854 }
2855
2856
2857 5.高精度乘10
2858 语法:multiply10(hp &a);
2859 参数:
2860 a:进行乘法的高精度数字
2861 返回值:返回结果到 a 中
2862 源程序:
2863 void multiply10(hp &a)
2864 {
2865 int i;
2866 for(i=a.len;i>=1;i--)
2867 a.s[i+1]=a.s[i];
2868 a.s[1]=0;
2869 a.len++;
2870 while(a.len>1&&a.s[a.len]==0) a.len--;
2871 }
2872
2873
2874 6.高精度乘单精度
2875 语法:multiply(const hp &a,int b,hp &c);
2876 参数:
2877 a:进行乘法的高精度数字
2878 b:进行乘法的单精度数字
2879 返回值:返回结果到 c 中
2880 源程序:
2881 void multiply(const hp &a,int b,hp &c)
2882 {
2883 int i,len;
2884 for(i=1;i<=maxsize;i++) c.s[i]=0;
2885 len=a.len;
2886 for(i=1;i<=len;i++)
2887 {
2888 c.s[i]+=a.s[i]*b;
2889 c.s[i+1]+=c.s[i]/10;
2890 c.s[i]%=10;
2891 }
2892 len++;
2893 while(c.s[len]>=10)
2894 {
2895 c.s[len+1]+=c.s[len]/10;
2896 c.s[len]%=10;
2897 len++;
2898 }
2899 while(len>1&&c.s[len]==0) len--;
2900 c.len=len;
2901 }
2902
2903
2904 7.高精度乘高精度
2905 语法:multiplyh(const hp &a,const hp &b,hp &c);
2906 参数:
2907 a,b:进行乘法的高精度数字
2908 返回值:返回结果到 c 中
2909 源程序:
2910 void multiplyh(const hp &a,const hp &b,hp &c)
2911 {
2912 int i,j,len;
2913 for(i=1;i<=maxsize;i++) c.s[i]=0;
2914 for(i=1;i<=a.len;i++)
2915 for(j=1;j<=b.len;j++)
2916 {
2917 c.s[i+j-1]+=a.s[i]*b.s[j];
2918 c.s[i+j]+=c.s[i+j-1]/10;
2919 c.s[i+j-1]%=10;
2920 }
2921 len=a.len+b.len+1;
2922 while(len>1&&c.s[len]==0) len--;
2923 c.len=len;
2924 }
2925
2926
2927 8.高精度除单精度
2928 语法:divide(const hp &a,int b,hp &c,int &d);
2929 参数:
2930 a:进行除法的高精度数字
2931 返回值:返回商到 c 中,余数到 d 中
2932 源程序:
2933 void divide(const hp &a,int b,hp &c,int &d)
2934 {
2935 int i,len;
2936 for(i=1;i<=maxsize;i++) c.s[i]=0;
2937 len=a.len;
2938 d=0;
2939 for(i=len;i>=1;i--)
2940 {
2941 d=d*10+a.s[i];
2942 c.s[i]=d/b;
2943 d%=b;
2944 }
2945 while(len>1&&c.s[len]==0) len--;
2946 c.len=len;
2947 }
2948
2949
2950 9.高精度除高精度
2951 语法:divideh(const hp &a,const hp &b,hp &c,hp &d);
2952 参数:
2953 a,b:进行除法的高精度数字
2954 返回值:返回商到 c 中,余数到 d 中
2955 注意:
2956 需要compare、multiply10、subtract
2957 源程序:
2958 void divideh(const hp &a,const hp &b,hp &c,hp &d)
2959 {
2960 hp e;
2961 int i,len;
2962 for(i=1;i<=maxsize;i++)
2963 {
2964 c.s[i]=0;
2965 d.s[i]=0;
2966 }
2967 len=a.len;
2968 d.len=1;
2969 for(i=len;i>=1;i--)
2970 {
2971 multiply10(d);
2972 d.s[1]=a.s[i];
2973 while(compare(d,b)>=0)
2974 {
2975 subtract(d,b,e);
2976 d=e;
2977 c.s[i]++;
2978 }
2979 }
2980 while(len>1&&c.s[len]==0) len--;
2981 c.len=len;
2982 }
2983
2984
2985
2986 九、标准模板库的使用
2987 1.计算求和
2988 TYPE accumulate( iterator start, iterator end, TYPE val );
2989
2990 The accummulate() function computes the sum of val and all of the elements in the range [start,end).
2991 #include <iostream>
2992 #include <vector>
2993 ////////////////////////////////////////////////////////////////用法1
2994 #include <numeric>
2995 using namespace std;
2996 int main ()
2997 {
2998 int arr[] = { 1,2,3,4,5 };
2999 vector<int> v(arr,arr+5);
3000
3001 // 1+2+3+4+5 and + 0
3002
3003 int sum = accumulate(v.begin(), v.end(), 0, );
3004 int sum
3005 cout << "sum = " << sum << endl;
3006 return 0;
3007 }
3008 //OUTPUT:
3009 // sum = 15
3010
3011 /////////////////////////////////////////////////////////////////////用法2
3012 #include <iostream>
3013 #include <vector>
3014 #include <numeric>
3015 using namespace std;
3016 int mul(int x,int y)
3017 {
3018 return x*y;
3019 }
3020 int main ()
3021 {
3022 int arr[] = { 1,2,3,4,5 };
3023 vector<int> v(arr,arr+5);
3024
3025 // 1+2+3+4+5 and + 0
3026 int sum = accumulate(v.begin(), v.end(), 1, mul);
3027 int sum
3028 cout << "sum = " << sum << endl;
3029 return 0;
3030 }
3031 //OUTPUT:
3032 // sum = 120
3033
3034 /////////////////////////////////////////////////////////////////////////////////////////////////用法3
3035 #include <iostream>
3036 #include <algorithm>
3037 #include <numeric>
3038 using namespace std;
3039
3040 int main ()
3041 {
3042 int x[] = {1,2,3,4,5};
3043
3044 // 1 * 2 * 3 * 4 * 5 and * 1
3045 int sum = accumulate(x, x+5, 1, multiplies<int>());
3046 cout << "sum = " << sum << endl;
3047
3048 // 1 * 2 * 3 * 4 * 5 and * 2
3049 sum = accumulate(x, x+5, 2, multiplies<int>());
3050 cout << "sum = " << sum << endl;
3051
3052 // 2 * 3 * 4 and * 10
3053 sum = accumulate(x+2, x+4, 10, multiplies<int>());
3054 cout << "sum = " << sum << endl;
3055
3056 return 0;
3057 }
3058 OUTPUT:
3059 // sum = 120
3060 // sum = 240
3061 // sum = 120
3062
3063 2.求数组中的最大值
3064
3065 max_element
3066 Syntax:
3067 #include <algorithm>
3068 iterator max_element( iterator start, iterator end );
3069 iterator max_element( iterator start, iterator end, BinPred p );
3070 The max_element() function returns an iterator to the largest element in the range [start,end).
3071 If the binary predicate p is given, then it will be used instead of the < operator to determine the largest element.
3072 Example code:
3073 For example, the following code uses the max_element() function to determine the largest integer in an array and the largest character in a vector of characters:
3074 int array[] = { 3, 1, 4, 1, 5, 9 };
3075 unsigned int array_size = 6;
3076 cout << "Max element in array is " << *max_element( array, array+array_size) << endl;
3077 Max element in array is 9
3078 3. sort和qsort
3079 1.sort
3080 用法:
3081 #include <algorithm>
3082 void sort( iterator start, iterator end );
3083 void sort( iterator start, iterator end, StrictWeakOrdering cmp );
3084
3085 例子:
3086
3087 #include<iostream>
3088 #include<algorithm>
3089 using namespace std;
3090 int cmp(int a,int b)
3091 {
3092 return a<b;
3093 }
3094 int main()
3095 {
3096 int a[10]={1,5,68,32,15,48,78,45,35,45};
3097 for(int i=0;i<10;i++)
3098 cout<<a[i]<<"\t";
3099 sort(a,a+10,cmp);
3100 cout<<endl;
3101 for(int i=0;i<10;i++)
3102 cout<<a[i]<<"\t";
3103 return 0;
3104 }
3105
3106
3107 2.qsort
3108 #include<cstdlib>
3109 一:对整型数据进行排序
3110 int num[100];
3111
3112 Sample:
3113
3114 int cmp ( const void *a , const void *b )
3115 {
3116 return *(int *)a - *(int *)b;
3117 }
3118
3119 qsort(num,100,sizeof(num[0]),cmp);
3120 二:对结构体进行排序
3121 struct In
3122 {
3123 double data;
3124 int other;
3125 }s[100];
3126
3127 //按照data的值从小到大将结构体排序,关于结构体内的排序关键数据data的类型可以很多种
3128
3129 int cmp( const void *a ,const void *b)
3130 {
3131 struct In *c=(In *)a;
3132 struct In *d=(In *)b;
3133 return c->data > d->data ? 1 : -1;
3134 }
3135
3136 qsort(s,100,sizeof(s[0]),cmp);
3137 九、其他
3138 1.运行时间计算.
3139 #include<time.h>
3140 clock_t start,finish;
3141 start=clock();
3142 finish=clock();
3143 cout<< (double)(finish - start) / CLOCKS_PER_SEC;//运行时间: