posts - 183,  comments - 10,  trackbacks - 0
 
之前有借助于 STL 中的 multimap 实现查找最小的 k 个元素。
这里继续解决 查找最小的 k 个元素,采用 最大根堆。

  1 #include <iostream>
  2 #include <ctime>
  3 #include <vector>
  4 using namespace std;
  5 
  6 class Heap
  7 {
  8 private:
  9     int* data;
 10     int  _size;
 11     int  _capacity;
 12 public:
 13     Heap()
 14     {
 15         _size = 0;
 16         _capacity = 2 * _size;
 17         data = new int[_capacity];
 18         if (data == 0)
 19         {
 20             exit(1);
 21         }
 22     }
 23     Heap(const Heap& h)
 24     {
 25         _size = h._size;
 26         _capacity = h._capacity;
 27         data = new int[_capacity];
 28         if (data == 0)
 29         {
 30             exit(1);
 31         }
 32         memcpy(data, h.data, sizeof (int* h._size);
 33     }
 34     Heap& operator =(const Heap& h)
 35     {
 36         delete [] data;
 37         _size = h._size;
 38         _capacity = h._capacity;
 39         data = new int[_capacity];
 40         if (data == 0)
 41         {
 42             exit(1);
 43         }
 44         memcpy(data, h.data, sizeof (int* h._size);
 45     }
 46     ~Heap()
 47     {
 48         delete [] data;
 49     }
 50     void insert(int item)
 51     {
 52         if (_size >= _capacity - 1)
 53         {
 54             _capacity = (_capacity + 1* 2;
 55             int * tmp = new int[_capacity];
 56             if (tmp == 0)
 57             {
 58                 exit(1);
 59             }
 60             // 1
 61             memcpy(tmp, data, sizeof (int* _capacity / 2 - 1);
 62             delete [] data;
 63             data = tmp;
 64         }
 65         data[++_size] = item;
 66         int pos1 = _size;
 67         int pos2 = pos1 / 2;
 68         while (pos2 >= 1 && data[pos1] > data[pos2])
 69         {
 70             data[pos1] ^= data[pos2];
 71             data[pos2] ^= data[pos1];
 72             data[pos1] ^= data[pos2];
 73             pos1 = pos2;
 74             pos2 = pos1 / 2;
 75         }
 76     }
 77     int max()
 78     {
 79         return data[1];
 80     }
 81     int erase()
 82     {
 83         int tmp = data[1];
 84         data[1= data[_size];
 85         --_size;
 86         int pos1 = 1, pos2;
 87         pos2 = pos1 * 2;
 88         
 89         while (pos2 <= _size)
 90         {
 91             if (pos2 < _size && data[pos2 + 1> data[pos2])
 92             {
 93                 ++pos2;
 94             }
 95             if (data[pos1] < data[pos2])
 96             {
 97                 data[pos1] ^= data[pos2];
 98                 data[pos2] ^= data[pos1];
 99                 data[pos1] ^= data[pos2];
100             }
101             pos1 = pos2;
102             pos2 = pos1 * 2;
103         }
104         return tmp;
105     }
106     int size()
107     {
108         return _size;
109     }
110     int capacity()
111     {
112         return _capacity;
113     }
114     void test()
115     {
116         for (int i = 1; i <= _size; ++i)
117         {
118             cout << data[i] << ' ';
119         }
120         cout << endl;
121     }
122 };
123 
124 void findMinK(Heap& h, int k, const vector<int>& data)
125 {
126     int m = 0;
127     for (vector<int>::const_iterator cit = data.begin(); cit != data.end(); ++cit)
128     {
129         if (m < k)
130         {
131             h.insert(*cit);
132             ++m;
133         }
134         else
135         {
136             if (*cit < h.max())
137             {
138                 h.erase();
139                 h.insert(*cit);
140             }
141         }
142     }
143 }
144 
145 int main()
146 {
147     int n = 100;
148     Heap h;
149     vector<int> data;
150     srand(time(0));
151     while (n--)
152     {
153         data.push_back(rand());
154     }
155     findMinK(h, 10, data);
156     for (vector<int>::const_iterator cit = data.begin(); cit != data.end(); ++cit)
157     {
158         cout << *cit << ' ';
159     }
160     cout << endl;
161     for (int i = 0; i < 10++i)
162     {
163         cout << h.erase() << endl;
164     }
165     cout << endl;
166     return 0;
167 }
posted @ 2011-04-27 00:03 unixfy 阅读(215) | 评论 (0)编辑 收藏
一个简单的堆的实现,大根堆。
  1 #include <iostream>
  2 #include <ctime>
  3 using namespace std;
  4 
  5 class Heap
  6 {
  7 private:
  8     int* data;
  9     int  _size;
 10     int  _capacity;
 11 public:
 12     Heap()
 13     {
 14         _size = 0;
 15         _capacity = 2 * _size;
 16         data = new int[_capacity];
 17         if (data == 0)
 18         {
 19             exit(1);
 20         }
 21     }
 22     Heap(const Heap& h)
 23     {
 24         _size = h._size;
 25         _capacity = h._capacity;
 26         data = new int[_capacity];
 27         if (data == 0)
 28         {
 29             exit(1);
 30         }
 31         memcpy(data, h.data, sizeof (int* h._size);
 32     }
 33     Heap& operator =(const Heap& h)
 34     {
 35         delete [] data;
 36         _size = h._size;
 37         _capacity = h._capacity;
 38         data = new int[_capacity];
 39         if (data == 0)
 40         {
 41             exit(1);
 42         }
 43         memcpy(data, h.data, sizeof (int* h._size);
 44     }
 45     ~Heap()
 46     {
 47         delete [] data;
 48     }
 49     void insert(int item)
 50     {
 51         if (_size >= _capacity - 1)
 52         {
 53             _capacity = (_capacity + 1* 2;
 54             int * tmp = new int[_capacity];
 55             if (tmp == 0)
 56             {
 57                 exit(1);
 58             }
 59             // 1
 60             memcpy(tmp, data, sizeof (int* _capacity / 2 - 1);
 61             delete [] data;
 62             data = tmp;
 63         }
 64         data[++_size] = item;
 65         int pos1 = _size;
 66         int pos2 = pos1 / 2;
 67         while (pos2 >= 1 && data[pos1] > data[pos2])
 68         {
 69             data[pos1] ^= data[pos2];
 70             data[pos2] ^= data[pos1];
 71             data[pos1] ^= data[pos2];
 72             pos1 = pos2;
 73             pos2 = pos1 / 2;
 74         }
 75     }
 76     int max()
 77     {
 78         return data[1];
 79     }
 80     int erase()
 81     {
 82         int tmp = data[1];
 83         data[1= data[_size];
 84         --_size;
 85         int pos1 = 1, pos2;
 86         pos2 = pos1 * 2;
 87         
 88         while (pos2 <= _size)
 89         {
 90             if (pos2 < _size && data[pos2 + 1> data[pos2])
 91             {
 92                 ++pos2;
 93             }
 94             if (data[pos1] < data[pos2])
 95             {
 96                 data[pos1] ^= data[pos2];
 97                 data[pos2] ^= data[pos1];
 98                 data[pos1] ^= data[pos2];
 99             }
100             pos1 = pos2;
101             pos2 = pos1 * 2;
102         }
103         return tmp;
104     }
105     int size()
106     {
107         return _size;
108     }
109     int capacity()
110     {
111         return _capacity;
112     }
113     void test()
114     {
115         for (int i = 1; i <= _size; ++i)
116         {
117             cout << data[i] << ' ';
118         }
119         cout << endl;
120     }
121 };
122 
123 int main()
124 {
125     int n = 10;
126     Heap h;
127     srand(time(0));
128     while (n--)
129     // for (int i = 0; i < 10; ++i)
130     {
131         h.insert(rand());
132         // h.insert(i);
133         // cout << h.size() << ' ' << h.capacity() << endl;
134     }
135     h.test();
136     for (int i = 0; i < 10++i)
137     {
138         cout << h.erase() << endl;
139     }
140     h.test();
141     return 0;
142 }
posted @ 2011-04-26 23:54 unixfy 阅读(146) | 评论 (0)编辑 收藏

直观的解法是对所有的 N 个数进行排序,再取最前或最后的 k 个元素。
这种做法的时间复杂度为 O(NlogN)

一种较好的解法是:维持一个 k 个元素的集合 S,遍历 N 个数,对每个元素,首先检查 S 中的元素个数是否小于 k,如果小于直接加入到 S 中。如果 S 中已有 k 个元素,则比较待处理元素与 S 中最大的元素的大小关系,若小于 S 中最大的元素,则删除 S 中最大的元素,并将该元素加入到 S 中。

怎样才能快速地从 S 中寻找到我们想要的最大的元素,使用堆是个好方法,最大堆。每次直接去堆的第一个元素即是 S 中最大的元素。如果将 S 中的最大元素删除,然后将 最后的一个元素放在堆顶,下滑,已调整堆。在讲新的元素加入到堆中,上滑,以调整堆。可以将这两个过程合并,即将 S 中最大的元素替换为 待处理的元素。对这个堆顶上的元素下滑,以调整堆。这里的复杂度为 O(Nlogk)。

STL 中的 multimap 不是堆,但是其可以以 O(logn) 维护其有序性,所以可以直接用 multimap 代替堆来实现。

http://zhedahht.blog.163.com/blog/static/2541117420072432136859/


 1 #include <iostream>
 2 #include <vector>
 3 #include <set>
 4 #include <ctime>
 5 using namespace std;
 6 
 7 void findMinK(multiset<int, greater<int> >& Kdata, int k, const vector<int>& data)
 8 {
 9     Kdata.clear();
10     int m = 0;
11     for (vector<int>::const_iterator cit = data.begin(); cit != data.end(); ++cit)
12     {
13         if (m < k)
14         {
15             Kdata.insert(*cit);
16             ++m;
17         }
18         else
19         {
20             if (*cit < *(Kdata.begin()))
21             {
22                 Kdata.erase(Kdata.begin());
23                 Kdata.insert(*cit);
24             }
25         }
26     }
27 }
28 
29 int main()
30 {
31     vector<int> data;
32     srand(time(0));
33     int n = 100;
34     while (n--)
35     {
36         data.push_back(rand());
37     }
38     multiset<int, greater<int> > Kdata;
39     findMinK(Kdata, 10, data);
40     for (vector<int>::const_iterator cit = data.begin(); cit != data.end(); ++cit)
41     {
42         cout << *cit << ' ';
43     }
44     cout << endl;
45     for (multiset<int, greater<int> >::const_iterator cit = Kdata.begin(); cit != Kdata.end(); ++cit)
46     {
47         cout << *cit << ' ';
48     }
49     cout << endl;
50     return 0;
51 }
posted @ 2011-04-26 22:59 unixfy 阅读(1135) | 评论 (3)编辑 收藏
来自于《大话设计模式》
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生时,会通知所有观察者对象,使他们自动更新自己。

行为型模式。

UML 类图:


代码实现 C++:
  1 #include <iostream>
  2 #include <string>
  3 #include <list>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 class Subject;
  8 
  9 class Observer
 10 {
 11 protected:
 12     string name;
 13     Subject* sub;
 14 public:
 15     Observer(const string& n, Subject* s) : name(n), sub(s) {}
 16     virtual void Update() = 0;
 17 };
 18 
 19 class Subject
 20 {
 21 protected:
 22     list<Observer*> observers;
 23     string action;
 24 public:
 25     virtual void Attach(Observer* ob) = 0;
 26     virtual void Detach(Observer* ob) = 0;
 27     virtual void Notify() = 0;
 28     virtual void setAction(const string& s) = 0;
 29     virtual string getAction() = 0;
 30 };
 31 
 32 class StockObserver : public Observer
 33 {
 34 public:
 35     StockObserver(const string& name, Subject* s) : Observer(name, s) {}
 36     virtual void Update()
 37     {
 38         cout << sub->getAction() << '\t' << name << " 关闭股票行情,继续工作!" << endl;
 39     }
 40 };
 41 
 42 class NBAObserver : public Observer
 43 {
 44 public:
 45     NBAObserver(const string& name, Subject* s) : Observer(name, s) {}
 46     virtual void Update()
 47     {
 48         cout << sub->getAction() << '\t' << name << " 关闭 NBA,继续工作!" << endl;
 49     }
 50 };
 51 
 52 class Boss : public Subject
 53 {
 54 //private:
 55 //    list<Observer*> observers;
 56 //    string action;
 57 public:
 58     virtual void Attach(Observer* ob)
 59     {
 60         observers.push_back(ob);
 61     }
 62     virtual void Detach(Observer* ob)
 63     {
 64         list<Observer*>::iterator iter= find(observers.begin(), observers.end(), ob);
 65         if (iter != observers.end())
 66         {
 67             observers.erase(iter);
 68         }
 69     }
 70     virtual void Notify()
 71     {
 72         for (list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
 73         {
 74             (*iter)->Update();
 75         }
 76     }
 77     virtual void setAction(const string& s)
 78     {
 79         action = s;
 80     }
 81     virtual string getAction()
 82     {
 83         return action;
 84     }
 85 };
 86 
 87 class Secretary : public Subject
 88 {
 89 //private:
 90 //    list<Observer*> observers;
 91 //    string action;
 92 public:
 93     virtual void Attach(Observer* ob)
 94     {
 95         observers.push_back(ob);
 96     }
 97     virtual void Detach(Observer* ob)
 98     {
 99         list<Observer*>::iterator iter = find(observers.begin(), observers.end(), ob);
100         if (iter != observers.end())
101         {
102             observers.erase(iter);
103         }
104     }
105     virtual void Notify()
106     {
107         for (list<Observer*>::iterator iter = observers.begin(); iter != observers.end(); ++iter)
108         {
109             (*iter)->Update();
110         }
111     }
112     virtual void setAction(const string& s)
113     {
114         action = s;
115     }
116     virtual string getAction()
117     {
118         return action;
119     }
120 };
121 
122 
123 
124 int main()
125 {
126     Boss* huhansan = new Boss;
127     StockObserver* so = new StockObserver("abc", huhansan);
128     NBAObserver*   no = new NBAObserver("xyz", huhansan);
129 
130     huhansan->Attach(so);
131     huhansan->Attach(no);
132     huhansan->setAction("我胡汉三又回来了!");
133     huhansan->Notify();
134 
135     huhansan->Detach(no);
136     huhansan->setAction("开会!");
137     huhansan->Notify();
138 
139     delete huhansan;
140 
141     Secretary* s = new Secretary;
142     s->Attach(no);
143     s->Attach(so);
144     s->setAction("老板来了!");
145     cout << s->getAction() << endl;
146     s->Notify();
147 
148     delete so;
149     delete no;
150     delete s;
151     
152     return 0;
153 }
posted @ 2011-04-26 19:28 unixfy 阅读(283) | 评论 (0)编辑 收藏
来自于《大话设计模式》
建造者模式(Builder):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

UML 类图:

代码实现 C++:
  1 #include <iostream>
  2 #include <string>
  3 #include <list>
  4 using namespace std;
  5 
  6 class Product
  7 {
  8 private:
  9     list<string> parts;
 10 public:
 11     void Add(string s)
 12     {
 13         parts.push_back(s);
 14     }
 15     void Show()
 16     {
 17         for (list<string>::const_iterator cit = parts.begin(); cit != parts.end(); ++cit)
 18         {
 19             cout << *cit << endl;
 20         }
 21     }
 22 };
 23 
 24 class Builder
 25 {
 26 public:
 27     Builder() {}
 28     virtual ~Builder() {}
 29     virtual void BuildPartA() = 0;
 30     virtual void BuildPartB() = 0;
 31     virtual Product* GetResult() = 0;
 32 };
 33 
 34 class ConcreteBuilder1 : public Builder
 35 {
 36 private:
 37     Product* p;
 38 public:
 39     ConcreteBuilder1() : p(new Product) {}
 40     virtual ~ConcreteBuilder1()
 41     {
 42         delete p;
 43     }
 44     virtual void BuildPartA()
 45     {
 46         p->Add("部件 A - 1");
 47     }
 48     virtual void BuildPartB()
 49     {
 50         p->Add("部件 B - 1");
 51     }
 52     virtual Product* GetResult()
 53     {
 54         return p;
 55     }
 56 };
 57 
 58 class ConcreteBuilder2 : public Builder
 59 {
 60 private:
 61     Product* p;
 62 public:
 63     ConcreteBuilder2() : p(new Product) {}
 64     virtual ~ConcreteBuilder2()
 65     {
 66         delete p;
 67     }
 68     virtual void BuildPartA()
 69     {
 70         p->Add("部件 A - 2");
 71     }
 72     virtual void BuildPartB()
 73     {
 74         p->Add("部件 B - 2");
 75     }
 76     virtual Product* GetResult()
 77     {
 78         return p;
 79     }
 80 };
 81 
 82 class Director
 83 {
 84 public:
 85     void Construct(Builder& b)
 86     {
 87         b.BuildPartA();
 88         b.BuildPartB();
 89     }
 90 };
 91 
 92 int main()
 93 {
 94     Director d;
 95     ConcreteBuilder1 b1;
 96     ConcreteBuilder2 b2;
 97 
 98     d.Construct(b1);
 99     Product* p1 = b1.GetResult();
100     p1->Show();
101     
102     d.Construct(b2);
103     Product* p2 = b2.GetResult();
104     p2->Show();
105 
106     return 0;
107 }
posted @ 2011-04-26 18:00 unixfy 阅读(227) | 评论 (0)编辑 收藏
来自于《大话设计模式》
外观模式(Facade):为子系统的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

UML 类图:

代码实现 C++:
 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Stock1
 5 {
 6 public:
 7     void Sell()
 8     {
 9         cout << "股票 1 卖出" << endl;
10     }
11     void Buy()
12     {
13         cout << "股票 1 买入" << endl;
14     }
15 };
16 
17 class Stock2
18 {
19 public:
20     void Sell()
21     {
22         cout << "股票 2 卖出" << endl;
23     }
24     void Buy()
25     {
26         cout << "股票 2 买入" << endl;
27     }
28 };
29 
30 class Stock3
31 {
32 public:
33     void Sell()
34     {
35         cout << "股票 3 卖出" << endl;
36     }
37     void Buy()
38     {
39         cout << "股票 3 买入" << endl;
40     }
41 };
42 
43 class Stock4
44 {
45 public:
46     void Sell()
47     {
48         cout << "股票 4 卖出" << endl;
49     }
50     void Buy()
51     {
52         cout << "股票 4 买入" << endl;
53     }
54 };
55 
56 class Fund
57 {
58 private:
59     Stock1* s1;
60     Stock2* s2;
61     Stock3* s3;
62     Stock4* s4;
63 public:
64     Fund() : s1(new Stock1), s2(new Stock2), s3(new Stock3), s4(new Stock4) {}
65     ~Fund()
66     {
67         delete s1;
68         delete s2;
69         delete s3;
70         delete s4;
71     }
72     void Sell()
73     {
74         s1->Sell();
75         s2->Sell();
76         s3->Sell();
77         s4->Sell();
78     }
79     void Buy()
80     {
81         s1->Buy();
82         s2->Buy();
83         s3->Buy();
84         s4->Buy();
85     }
86 };
87 
88 int main()
89 {
90     Fund f;
91     f.Buy();
92     f.Sell();
93     return 0;
94 }
posted @ 2011-04-26 15:49 unixfy 阅读(221) | 评论 (0)编辑 收藏
函数实现将网址进行如下操作
www.google.com 转成 com.google.www 及 mail.netease.com 转成 com.netease.mail
不允许用STL,空间为 O(1)

http://topic.csdn.net/u/20110425/12/8b5e155c-73d1-40af-84b8-6b6493f638e2.html

一开始把 O(1) 看做时间复杂度了,如果是空间复杂度,直接在原地两次翻转即可。整体翻转,部分翻转顺序可以任意。
 1 #include <iostream>
 2 using namespace std;
 3 
 4 void reverse_(char* s, int left, int right)
 5 {
 6     while (left < right)
 7     {
 8         s[left]  ^= s[right];
 9         s[right] ^= s[left];
10         s[left]  ^= s[right];
11         ++left;
12         --right;
13     }
14 }
15 
16 int findch(char* s, char c, int n)
17 {
18     int ret, len = strlen(s);
19     for (ret = n; ret < len; ++ret)
20     {
21         if (s[ret] == c)
22         {
23             return ret;
24         }
25     }
26     return -1;
27 }
28 
29 char* reverse(char* s)
30 {
31     reverse_(s, 0, strlen(s) - 1);
32     int left = 0, right = findch(s, '.', left);
33     while (right != -1)
34     {
35         reverse_(s, left, right - 1);
36         left = right + 1;
37         right = findch(s, '.', left);
38     }
39     reverse_(s, left, strlen(s) - 1);
40     return s;
41 }
42 
43 int main()
44 {
45     char s[100];
46     while (cin >> s)
47     {
48         cout << reverse(s) << endl;
49     }
50     return 0;
51 }


如果是时间复杂度呢?
这里由个限制,就是只有两个 . 符号时才成立。使用字符串数组存储字符串,将首尾字符串指针交换即可。
例如 mail.netease.com
存在于字符串指针数组中:
mail
.
netease
.
com
将指向 mail 和 指向 com 的两个字符串指针交换即可。
 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     char* s[100];
 7     int i;
 8     for (i = 0; i < 100++i)
 9     {
10         s[i] = new char[100];
11     }
12     char c;
13     i = 0;
14     int j = 0;
15     // while (cin >> c)
16     // while (scanf("%c", &c))
17     while (c = getchar())
18     {
19         if (c == '\n')
20         {
21             break;
22         }
23         if (c != '.')
24         {
25             s[i][j] = c;
26             ++j;
27             s[i][j] = '\0';
28         }
29         else
30         {
31             // s[i][j] = '\0';
32             ++i;
33             s[i][0= c;
34             s[i][1= '\0';
35             j = 0;
36             ++i;
37         }
38     }
39     char* t = s[0];
40     s[0= s[i];
41     s[i] = t;
42     for (j = 0; j <= i; ++j)
43     {
44         cout << s[j];
45     }
46     cout << endl;
47     return 0;
48 }
posted @ 2011-04-25 23:18 unixfy 阅读(232) | 评论 (0)编辑 收藏
来自于《大话设计模式》
模板方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

尽量将公共操作上移到基类中,这样便于修改,代码复用性更强。

UML 类图:


代码实现 C++:
 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 class TestPaper
 6 {
 7 public:
 8     virtual void TestQuestion1()
 9     {
10         cout << "TestQuestion1" << endl;
11         cout << "Answer: " << Answer1() << endl;
12     }
13     virtual void TestQuestion2()
14     {
15         cout << "TestQuestion2" << endl;
16         cout << "Answer: " << Answer2() << endl;
17     }
18     virtual void TestQuestion3()
19     {
20         cout << "TestQuestion3" << endl;
21         cout << "answer: " << Answer3() << endl;
22     }
23     virtual const string Answer1() = 0
24     {
25         return "";
26     }
27     virtual const string Answer2() = 0
28     {
29         return "";
30     }
31     virtual const string Answer3() = 0
32     {
33         return "";
34     }
35 };
36 
37 class TestPaperA : public TestPaper
38 {
39 public:
40     virtual const string Answer1()
41     {
42         return "a";
43     }
44     virtual const string Answer2()
45     {
46         return "b";
47     }
48     virtual const string Answer3()
49     {
50         return "c";
51     }
52 };
53 
54 class TestPaperB : public TestPaper
55 {
56 public:
57     virtual const string Answer1()
58     {
59         return "c";
60     }
61     virtual const string Answer2()
62     {
63         return "b";
64     }
65     virtual const string Answer3()
66     {
67         return "a";
68     }
69 };
70 
71 int main()
72 {
73     TestPaperA a;
74     a.TestQuestion1();
75     a.TestQuestion2();
76     a.TestQuestion3();
77 
78     TestPaperB b;
79     b.TestQuestion1();
80     b.TestQuestion2();
81     b.TestQuestion3();
82 
83     TestPaper* p;
84     p = new TestPaperA;
85     p->TestQuestion1();
86     p->TestQuestion2();
87     p->TestQuestion3();
88     delete p;
89 
90     p = new TestPaperB;
91     p->TestQuestion1();
92     p->TestQuestion2();
93     p->TestQuestion3();
94     delete p;
95 
96     return 0;
97 }
posted @ 2011-04-25 16:41 unixfy 阅读(154) | 评论 (0)编辑 收藏
来自于《大话设计模式》
原型模式(Prototype):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

这个设计模式在 C++ 中如何实现?

UML 图:

代码实现 C++:
  1 #include <iostream>
  2 using namespace std;
  3 
  4 class Prototype
  5 {
  6 public:
  7     virtual Prototype& Clone() = 0;
  8 };
  9 
 10 class ConcretePrototype
 11 {
 12 private:
 13     int m;
 14     char* str;
 15 public:
 16     ConcretePrototype(int n = 0const char* s = "") : m(n)
 17     {
 18         str = new char[strlen(s) + 1];
 19         if (str == 0)
 20         {
 21             exit(1);
 22         }
 23         strcpy(str, s);
 24     }
 25     ConcretePrototype(const ConcretePrototype& p)
 26     {
 27         str = new char[strlen(p.str) + 1];
 28         if (str == 0)
 29         {
 30             exit(1);
 31         }
 32         strcpy(str, p.str);
 33         m = p.m;
 34     }
 35     ConcretePrototype& operator =(const ConcretePrototype& p)
 36     {
 37         if (this == &p)
 38         {
 39             delete [] str;
 40             str = new char[strlen(p.str) + 1];
 41             if (str == 0)
 42             {
 43                 exit(1);
 44             }
 45             strcpy(str, p.str);
 46             m = p.m;
 47         }
 48         return *this;
 49     }
 50     ~ConcretePrototype()
 51     {
 52         delete [] str;
 53     }
 54     ConcretePrototype& Clone()
 55     {
 56         return *this;
 57     }
 58     void SetStr(const char* s = "")
 59     {
 60         delete [] str;
 61         str = new char[strlen(s) + 1];
 62         if (str == 0)
 63         {
 64             exit(1);
 65         }
 66         strcpy(str, s);
 67     }
 68     void SetM(int n)
 69     {
 70         m = n;
 71     }
 72     void SetStrAndM(const char* s, int n)
 73     {
 74         delete [] str;
 75         str = new char[strlen(s) + 1];
 76         if (str == 0)
 77         {
 78             exit(1);
 79         }
 80         strcpy(str, s);
 81         m = n;
 82     }
 83     void test()
 84     {
 85         cout << m << endl;
 86         cout << str << endl;
 87     }
 88 };
 89 
 90 int main()
 91 {
 92     ConcretePrototype c(5"abc");
 93     c.test();
 94 
 95     ConcretePrototype c2 = static_cast<ConcretePrototype>(c.Clone());
 96     c2.test();
 97 
 98     c2.SetStrAndM("xyz"7);
 99     c2.test();
100 
101     return 0;
102 
103 }

posted @ 2011-04-25 16:03 unixfy 阅读(285) | 评论 (0)编辑 收藏

来自于《大话设计模式》
工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

有一个操作类 Operation,继承其而派生出具体各个操作的操作派生类。
产生操作类的工厂基类 IFactory,继承其而派生出产生具体操作类的工厂派生类。

UML 类图:


代码实现 C++:

  1 #include <iostream>
  2 #include <cmath>
  3 using namespace std;
  4 
  5 class Operation
  6 {
  7 protected:
  8     double NumberA;
  9     double NumberB;
 10 public:
 11     virtual void SetNumberA(double a)
 12     {
 13         NumberA = a;
 14     }
 15     virtual void SetNumberB(double b)
 16     {
 17         NumberB = b;
 18     }
 19     virtual double GetResult() = 0;
 20 };
 21 
 22 class OperationAdd : public Operation
 23 {
 24 public:
 25     virtual double GetResult()
 26     {
 27         return NumberA + NumberB;
 28     }
 29 };
 30 
 31 class OperationSub : public Operation
 32 {
 33 public:
 34     virtual double GetResult()
 35     {
 36         return NumberA - NumberB;
 37     }
 38 };
 39 
 40 class OperationMul : public Operation
 41 {
 42 public:
 43     virtual double GetResult()
 44     {
 45         return NumberA * NumberB;
 46     }
 47 };
 48 
 49 class OperationDiv : public Operation
 50 {
 51 public:
 52     virtual double GetResult()
 53     {
 54         if (NumberB == 0)
 55         {
 56             throw runtime_error("NumberB = 0!");
 57         }
 58         return NumberA / NumberB;
 59     }
 60 };
 61 
 62 class OperationPow : public Operation
 63 {
 64 public:
 65     virtual double GetResult()
 66     {
 67         if (NumberA == 0 && NumberB <= 0)
 68         {
 69             throw runtime_error("NumberA = 0, NumberB <= 0!");
 70         }
 71         return pow(NumberA, NumberB);
 72     }
 73 };
 74 
 75 class IFactory
 76 {
 77 public:
 78     virtual Operation* CreateOperation() = 0;
 79 };
 80 
 81 class AddFactory : public IFactory
 82 {
 83 public:
 84     virtual Operation* CreateOperation()
 85     {
 86         return new OperationAdd;
 87     }
 88 };
 89 
 90 class SubFactory : public IFactory
 91 {
 92 public:
 93     virtual Operation* CreateOperation()
 94     {
 95         return new OperationSub;
 96     }
 97 };
 98 
 99 class MulFactory : public IFactory
100 {
101 public:
102     virtual Operation* CreateOperation()
103     {
104         return new OperationMul;
105     }
106 };
107 
108 class DivFactory : public IFactory
109 {
110 public:
111     virtual Operation* CreateOperation()
112     {
113         return new OperationDiv;
114     }
115 };
116 
117 class PowFactory : public IFactory
118 {
119 public:
120     virtual Operation* CreateOperation()
121     {
122         return new OperationPow;
123     }
124 };
125 
126 int main()
127 {
128     double a, b;
129     while (cin >> a >> b)
130     {
131         IFactory* pfactory = new AddFactory;
132         Operation* poperation = pfactory->CreateOperation();
133         poperation->SetNumberA(a);
134         poperation->SetNumberB(b);
135         cout << poperation->GetResult() << endl;
136         delete pfactory;
137         delete poperation;
138 
139         pfactory = new SubFactory;
140         poperation = pfactory->CreateOperation();
141         poperation->SetNumberA(a);
142         poperation->SetNumberB(b);
143         cout << poperation->GetResult() << endl;
144         delete pfactory;
145         delete poperation;
146 
147         pfactory = new MulFactory;
148         poperation = pfactory->CreateOperation();
149         poperation->SetNumberA(a);
150         poperation->SetNumberB(b);
151         cout << poperation->GetResult() << endl;
152         delete pfactory;
153         delete poperation;
154 
155         pfactory = new DivFactory;
156         poperation = pfactory->CreateOperation();
157         poperation->SetNumberA(a);
158         poperation->SetNumberB(b);
159         try
160         {
161             cout << poperation->GetResult() << endl;
162         }
163         catch (const runtime_error& e)
164         {
165             cerr << e.what() << endl;
166         }
167         delete pfactory;
168         delete poperation;
169 
170         pfactory = new PowFactory;
171         poperation = pfactory->CreateOperation();
172         poperation->SetNumberA(a);
173         poperation->SetNumberB(b);
174         cout << poperation->GetResult() << endl;
175         delete pfactory;
176         delete poperation;
177     }
178 }
posted @ 2011-04-25 15:30 unixfy 阅读(202) | 评论 (0)编辑 收藏
仅列出标题
共19页: First 11 12 13 14 15 16 17 18 19