编程珠玑(第二版)系列算法实现

最近开始攻读编程珠玑,这里将实现的部分程序汇集起来,使用的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\n",a[i]);
21     }
22     printf("\n");
23 
24     system("pause");
25     return 0;
26 }
View Code

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 }
View Code

(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 }
View Code

 第二章:

(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 }
View Code

 第八章:

四种算法实现求一个数组中的最大连续子向量和,分别为简单算法(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<<"\nTime:"<<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<<"\nTime:"<<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<<"\nTime:"<<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<<"\nTime:"<<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<<"\nTime:"<<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 }
View Code

延伸:如果要找的是和最接近0的连续子向量,该如何做呢?此时应当在算法2b的基础上得到数组cumarr(cumarr[i] = x[0]+x[1]+...+x[i]),然后对数组cumarr排序,相邻元素做差,找出cumarr中最接近的两个元素。基本原理:如果cumarr[i-1] = cumarr[j],那么x[i..j]的和为0。

posted on 2013-07-11 14:21  Sophia-呵呵小猪  阅读(410)  评论(0编辑  收藏  举报