最近开始攻读编程珠玑,这里将实现的部分程序汇集起来,使用的IDE是VS 2010.
第一章:
(1)内存足够情况下,使用C/C++标准库函数实现数组排序
C库函数实现:

1 #include "stdafx.h" 2 #include <iostream> 3 #include <cstdlib> 4 using namespace std; 5 6 int intcomp(const void* x,const void* y) 7 { 8 return *(int*)x-*(int*)y; 9 } 10 int _tmain(int argc, _TCHAR* argv[]) 11 { 12 const int n = 5; 13 int a[n]; 14 int i = 0; 15 while(scanf("%d", &a[i]) != EOF) 16 ++i; 17 qsort(a, n, sizeof(int), intcomp); 18 for(i = 0; i < n; i++) 19 { 20 printf("%d ",a[i]); 21 } 22 printf(" "); 23 24 system("pause"); 25 return 0; 26 }
C++库函数实现:

1 #include "stdafx.h" 2 #include <iostream> 3 #include <set> 4 using namespace std; 5 6 int _tmain(int argc, _TCHAR* argv[]) 7 { 8 set<int> s; 9 int i; 10 while(cin>>i) 11 s.insert(i); 12 13 for(set<int>::iterator iter = s.begin(); iter != s.end(); iter++) 14 cout<<*iter<<endl; 15 16 system("pause"); 17 return 0; 18 }
(2)使用位逻辑运算(如与、或、移位)来实现位向量并用此实现位排序

1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 const int bitsPerWord = 32; 6 const int shift = 5; 7 const int mask = 0x1F; 8 const int N = 10000000; 9 int a[1+N/bitsPerWord]; 10 11 void set(int i) 12 { 13 a[i>>shift] |= (1<<(i & mask)); 14 } 15 void clr(int i) 16 { 17 a[i>>shift] &= ~(1<<(i & mask)); 18 } 19 int test(int i) 20 { 21 return a[i>>shift] & (1<<(i & mask)); 22 } 23 24 int _tmain(int argc, _TCHAR* argv[]) 25 { 26 int i; 27 for(i = 0; i < N; i++) 28 clr(i); 29 30 while(cin>>i) 31 set(i); 32 for(i = 0; i < N; i++) 33 if(test(i)) 34 cout<<i<<endl; 35 36 system("pause"); 37 return 0; 38 }
第二章:
(3)实现2.3节讲述的类似杂技的向量旋转代码

1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 int _tmain(int argc, _TCHAR* argv[]) 6 { 7 const int n = 9; 8 char x[n+1] = "cbfdgehai"; 9 cout<<x<<endl; 10 11 int rotdist = 3; 12 for(int i = 0; i < rotdist; i++) 13 { 14 int t = x[i]; 15 int j = i; 16 while(1) 17 { 18 int k = j + rotdist; 19 if(k >= n) 20 k -= n; 21 if(k == i) 22 break; 23 x[j] = x[k]; 24 j = k; 25 x[j] = t; 26 } 27 } 28 29 cout<<x<<endl; 30 system("pause"); 31 return 0; 32 }
第八章:
四种算法实现求一个数组中的最大连续子向量和,分别为简单算法(O(n^3)),平方算法(O(n^2)),分治算法(O(nlogn)),扫描算法(O(n))。C++实现如下:

1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 #include <time.h> 5 6 void maxsum1(int a[], int n) 7 { 8 int start = clock(); 9 if(n < 1) 10 return; 11 int maxsofar = 0; 12 for(int i = 0;i < n; i++) 13 { 14 for(int j = i; j < n; j++) 15 { 16 int sum = 0; 17 for(int k = i; k <= j;k++) 18 { 19 sum += a[k]; 20 maxsofar = max(sum,maxsofar); 21 } 22 } 23 } 24 int time = clock()-start; 25 cout<<"maxsum:"<<maxsofar<<" Time:"<<time<<endl; 26 } 27 28 void maxsum2a(int a[], int n) 29 { 30 int start = clock(); 31 if(n < 1) 32 return; 33 int maxsofar = 0; 34 for(int i = 0; i< n; i++) 35 { 36 int sum = 0; 37 for(int j = i; j < n; j++) 38 { 39 sum += a[j]; 40 maxsofar = max(maxsofar, sum); 41 } 42 } 43 int time = clock()-start; 44 cout<<"maxsum2a:"<<maxsofar<<" Time:"<<time<<endl; 45 } 46 47 void maxsum2b(int a[], const int n) 48 { 49 int start = clock(); 50 if(n < 1) 51 return; 52 const int LEN = 100; 53 int cumarr[LEN] = { 0 }; 54 for(int i = 0; i < n; i++) 55 { 56 cumarr[i+1] = cumarr[i]+a[i]; 57 } 58 int maxsofar = 0; 59 for(int i = 0; i < n; i++) 60 { 61 for(int j = i; j < n; j++) 62 { 63 int sum = cumarr[j+1]-cumarr[i]; 64 maxsofar = max(maxsofar, sum); 65 } 66 } 67 int time = clock()-start; 68 cout<<"maxsum2b:"<<maxsofar<<" Time:"<<time<<endl; 69 } 70 71 int maxsum3Rev(int a[], int l, int r) 72 { 73 if(l > r) 74 return 0; 75 if(l == r) 76 return a[l]; 77 int m = (l+r)/2; 78 int lmax = 0; 79 int rmax = 0; 80 int sum = 0; 81 for(int i = m; i >= l; i--) 82 { 83 sum += a[i]; 84 lmax = max(lmax, sum); 85 } 86 sum = 0; 87 for(int j = m+1; j <= r; j++) 88 { 89 sum += a[j]; 90 rmax = max(rmax, sum); 91 } 92 int maxsum = max(maxsum3Rev(a,l,m), maxsum3Rev(a,m+1,r)); 93 maxsum = max(maxsum,lmax+rmax); 94 95 return maxsum; 96 } 97 98 void maxsum3(int a[], int n) 99 { 100 int start = clock(); 101 if(n < 1) 102 return; 103 int maxsum = maxsum3Rev(a,0,n-1); 104 int time = clock()-start; 105 cout<<"maxsum3:"<<maxsum<<" Time:"<<time<<endl; 106 } 107 108 void maxsum4(int a[],int n) 109 { 110 int start = clock(); 111 int maxsofar = 0; 112 int maxendinghere = 0; 113 for(int i = 0; i < n; i++) 114 { 115 maxendinghere = max(maxendinghere + a[i], 0); 116 maxsofar = max(maxsofar, maxendinghere); 117 } 118 int time = clock()-start; 119 cout<<"maxsum4:"<<maxsofar<<" Time:"<<time<<endl; 120 } 121 122 int _tmain(int argc, _TCHAR* argv[]) 123 { 124 int a[] = {3, 2, 1, -13, 10, -2, -1,6}; 125 maxsum1(a,8); 126 maxsum2a(a,8); 127 maxsum2b(a,8); 128 maxsum3(a,8); 129 maxsum4(a,8); 130 131 system("pause"); 132 return 0; 133 }
延伸:如果要找的是和最接近0的连续子向量,该如何做呢?此时应当在算法2b的基础上得到数组cumarr(cumarr[i] = x[0]+x[1]+...+x[i]),然后对数组cumarr排序,相邻元素做差,找出cumarr中最接近的两个元素。基本原理:如果cumarr[i-1] = cumarr[j],那么x[i..j]的和为0。