amdb

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SparseVector.hh

 1 class SparseVector
 2 {
 3 private:
 4     //结构体不一定会用到,不用初始化
 5     struct node
 6     {
 7         int index;
 8         int value;
 9         node *next;
10         
11         node(int index, int value, node *next = 0) : index(index), value(value), next(next) {}
12     };
13     //这些才是真正的数据成员,要初始化的
14     int size;
15     node *start;    
16 
17     void clear();
18     void copyList(const SparseVector &sv);
19     void setNonzeroElem(int index, int value);
20     void removeElem(int index);
21     void checkListOrder();
22     void addSubVector(const SparseVector &sv, bool add);
23     void removeZeros();
24     void checkZeros();
25 public:
26     SparseVector(int size);
27     const int getSize()const;
28 
29     ~SparseVector();
30     SparseVector(const SparseVector &sv);
31     SparseVector & operator= (const SparseVector &sv);
32     int getElem(int idx);
33     void setElem(int index, int value);
34     bool operator==(const SparseVector &sv)const;
35     bool operator!=(const SparseVector &sv)const;
36     SparseVector& operator+=(const SparseVector &sv);
37     SparseVector& operator-=(const SparseVector &sv);
38     const SparseVector& operator+(const SparseVector &sv)const;
39     const SparseVector& operator-(const SparseVector &sv)const;
40 };
View Code

SparseVector.cc

  1 #include "SparseVector.hh"
  2 #include <cassert>
  3 #include <iostream>
  4 using namespace std;
  5 //单参数构造函数
  6 SparseVector::SparseVector(int size):size(size)
  7 {
  8     start = 0;
  9 }
 10 
 11 const int SparseVector::getSize()const
 12 {
 13     return size;
 14 }
 15 //成员函数都默认带有this指针,所以默认对调用这个函数的对象进行操作,所以不用再传本对象的地址了。
 16 void SparseVector::clear()
 17 {
 18     node *next;
 19     node *current;    
 20     current = start;
 21     while(current != 0)
 22     {
 23         next = current->next;
 24         delete current;
 25         current = next;
 26     }
 27     start = 0;
 28 }
 29 //对本对象进行操作,调用成员行数也是默认对本对象进行操作,不用传本对象地址。
 30 SparseVector::~SparseVector()
 31 {
 32     clear();
 33 }
 34 
 35 void SparseVector::copyList(const SparseVector &sv)
 36 {
 37     size = sv.getSize();
 38     node *current;
 39     node *otherCurrent =sv.start;
 40     node *prev = 0;
 41 
 42     while(otherCurrent != 0)
 43     {
 44         current = new node(otherCurrent->index, otherCurrent->value);
 45         if(prev == 0)
 46         {
 47             start = current;
 48             prev = current;
 49         }
 50         prev->next = current;
 51         prev = current;
 52         otherCurrent = otherCurrent->next;
 53     }
 54 }
 55 
 56 SparseVector::SparseVector(const SparseVector &sv)
 57 {
 58     copyList(sv);
 59 }
 60 //注意自赋值,并且直接调用私有帮助函数。
 61 SparseVector & SparseVector:: operator= (const SparseVector &sv)
 62 {
 63     if (this == &sv)
 64     {
 65         return *this;
 66     }
 67     clear();
 68     copyList(sv);
 69     return *this;
 70 }
 71 //难点
 72 int SparseVector::getElem(int idx)
 73 {
 74     node *current = start;
 75     while(current != 0 && current->index < idx)//过滤,两个条件
 76     {
 77         current = current->next;
 78     }
 79     if(current == 0)//注意判断条件先后次序,先排除current为0情况
 80     {
 81         return 0;
 82     }
 83     else if(current->index == idx)//如果先执行这个,则current为0时,会直接产生段错误
 84     {
 85         return current->value;
 86     }    
 87     else 
 88     {
 89         return 0;
 90     }
 91 }
 92 //难点,分种情况讨论:1,初始为空。2,插到最后面。3,插到最前面。4,插到中间。
 93 void SparseVector::setNonzeroElem(int index, int value)
 94 {
 95     assert(value != 0);
 96     node *current = start;
 97     node *prev = 0;
 98     
 99     if(start == 0)//容易遗漏,链表初始为空的情况。(1)
100     {
101         start = new node(index, value);
102     }    
103     else//除此情况外(2,3,4)
104     {
105         while(current != 0 && current->index < index)//过滤,两个条件,保证current指向应该指的结点,或其之后的结点。prev指向值小于应该的结点。
106         {
107             prev = current;
108             current = current->next;//别忘了自增
109         }
110     /*2选1
111      *     if(current == start)//插到最前面,current所指结点大于等于它
112         {
113             if(current->index == index)//等于
114             {    
115                 current->value = value;
116             }
117             else//大于
118             {
119                 node *other = new node(index, value, start);
120                 start = other;
121             }
122         }    
123         else if(current == 0)//插到最后面,current所指结点小于它
124         {
125             node *other = new node(index, value, 0);
126             prev->next = other;
127         }
128         else//插到中间,current所指结点大于等于它
129         {
130             if(current->index == index)//current所指结点等于它
131             {
132                 current->value = value;
133             }
134             else//current所指结点结点大于它
135             {
136                 node *other = new node(index, value, current);
137                 prev->next = other;
138             }
139         }
140 */
141         if(current == 0)//插到最后边
142         {
143             node *other = new node(index, value);
144             prev->next = other;
145         }
146         else if(current -> index == index)//current所指结点等于它的值
147         {
148             current->value =value;
149         }
150         else if(current == start)//在最开始的地方
151         {
152             node *other = new node(index, value, start);
153             start = other;
154         }
155         else //在中间
156         {
157             node *other = new node(index, value, current);
158             prev->next = other;        
159         }
160     }
161 }
162 
163 void SparseVector::removeElem(int index)
164 {
165     node *current = start;
166     node *prev = 0;
167     while(current != 0 && current->index < index)//过滤
168     {
169         prev = current;
170         current = current->next;
171     }
172     if(current->index == index)//如果是这个结点
173     {
174         if(current == start)//是开始结点
175         {
176             prev = current;
177             current = current->next;
178             delete prev;
179             start = current;
180             return; 
181         }
182         else//是中间结点或者是后边的节点(相同的)
183         {
184             prev->next = current->next;
185             delete current;
186             return;
187         }
188     }
189     else 
190     {
191         return;
192     }
193 }
194 
195 void SparseVector::setElem(int index, int value)
196 {
197     if(value != 0)
198     {
199         setNonzeroElem(index, value);
200     }
201     else
202     {
203         removeElem(index);
204     }
205 }
206 
207 void SparseVector::checkListOrder()
208 {
209     node *current = start;
210     while(current != 0)
211     {
212         cout<<"("<<current->index<<"  |  "<<current->value<<")"<<endl;
213         current = current->next;
214     }
215     return;
216 }
217 
218 bool SparseVector::operator==(const SparseVector &sv)const
219 {
220     if(size != sv.size)//先判断是不是size不等,直接排除
221     {
222         return false;
223     }
224     else//每个结点依次判断index和value
225     {
226         node *current = start;
227         node *otherCurrent = sv.start;
228         while(current != 0 && otherCurrent != 0)
229         {
230             if(current->index != otherCurrent->index || current->value != otherCurrent->value)
231             {
232                 return false;
233             }
234             current = current->next;
235             otherCurrent = otherCurrent->next;
236         }
237         if(current == 0 && otherCurrent == 0)//看看还有没有哪个剩余结点
238         {
239             return true;
240         }
241         else
242         {
243             return false;
244         }
245     }
246 }
247 
248 bool SparseVector::operator!=(const SparseVector &sv)const
249 {
250     return !(*this == sv);//调用等号,结果取反
251 }
252 
253 void SparseVector::addSubVector(const SparseVector &sv, bool add)
254 {
255     node *current = start;
256     node *otherCurrent = sv.start;
257     node *prev = 0;
258     int sign = (add ? 1 : -1);//注意符号处理方式
259 
260     if(current == 0)//两个链表合并时,一定不能忽略被合并链表为空的情况:(a+=b,其中a为空)
261     { 
262         if(otherCurrent == 0)//(ab均为空)
263         {
264             return;
265         }
266         else
267         {
268             while(otherCurrent != 0)//(a为空b不为空)参考直接插入法形成一个新链表
269             {
270                 node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, 0);
271                 if(prev == 0)
272                 {    
273                     start = addTo;
274                     prev = addTo;
275                     current = addTo;
276                 }
277                 else
278                 {
279                     current->next = addTo;
280                     current = addTo;  
281                 }
282                 otherCurrent = otherCurrent->next;
283             }
284             return;
285         }   
286     }
287     else//合并时均非空的情况
288     {
289         while(current != 0 && otherCurrent != 0)//都顺序遍历,直到某一链表结束
290         {
291             if(current->index > otherCurrent->index)//插入的
292             {
293                 if(prev == 0)//初始结点
294                 {
295                     node *addTo = new node (otherCurrent->index, sign * otherCurrent->value, current);
296                     start = addTo;
297                     prev = addTo;
298                     otherCurrent = otherCurrent->next;
299                 }
300                 else//非初始结点
301                 {
302                     node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current);
303                     prev->next = addTo;
304                     prev = addTo;
305                     otherCurrent = otherCurrent->next;
306                 }            
307             }
308             else if(current->index == otherCurrent->index)//直接加减的
309             {
310                 current->value += sign * otherCurrent->value;
311                 prev = current;
312                 current = current->next;
313                 otherCurrent = otherCurrent->next; 
314             }
315             else if(current->index < otherCurrent->index)//不插入的
316             {
317                 prev = current;
318                 current = current->next;
319             }
320         }
321         if(otherCurrent == 0)//处理剩余的结点
322         {
323             return;
324         }
325         else//把剩余的插入到原来的
326         {
327             while(otherCurrent != 0)
328             {
329                 node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current);
330                 prev->next = addTo;
331                 prev = addTo;
332                 otherCurrent = otherCurrent->next;
333             }
334         }
335         return;
336     }    
337 }
338 
339 void SparseVector::removeZeros()
340 {
341     node *current = start;
342     node *prev = 0;
343     while(current != 0)//非0状态
344     {
345         if(current->value != 0)
346         {
347             prev = current;
348             current = current->next;
349         }
350         else//为0状态
351         {
352             if(prev == 0)//如果初始结点为0
353             {
354                 prev = current;
355                 current = current->next;
356                 delete prev;
357                 start = current;
358                 prev = 0;
359             }
360             else//非初始结点为0
361             {
362                 node *temp = current;
363                 current = current->next;
364                 delete temp;
365                 prev->next = current;
366             }
367         }
368     }
369 }
370 
371 SparseVector& SparseVector::operator+=(const SparseVector &sv)
372 {
373     addSubVector(sv, true);
374     removeZeros();
375     node * current = start;
376     size = 0;
377     while(current != 0)//最后还要把size弄好
378     {
379         ++size;
380         current = current->next;
381     }
382     return *this;
383 }
384 
385 SparseVector& SparseVector::operator-=(const SparseVector &sv)
386 {
387     addSubVector(sv, false);
388     removeZeros();
389     size = 0;
390     node *current = start;
391     while(current != 0)//最后还要把size弄好
392     {
393         ++size;
394         current = current->next;
395     }
396     return *this;
397 }
398 
399 const SparseVector& SparseVector::operator+(const SparseVector &sv)const
400 {
401     SparseVector *newSp = new SparseVector(*this);
402     *newSp += sv;
403     return *newSp;
404 }
405 
406 const SparseVector& SparseVector::operator-(const SparseVector &sv)const
407 {
408     SparseVector *newSp = new SparseVector(*this);
409     *newSp -= sv;
410     return *newSp;
411 }
412 
413 void SparseVector::checkZeros()
414 {
415     node *current = start;
416     while(current != 0)
417     {
418         if(current->value == 0)
419         {
420             cout<<"number "<<current->index<<"  "<<current->value<<endl;
421             current = current->next;
422         }
423     }
424 }
View Code

 

posted on 2015-04-30 10:28  amdb  阅读(363)  评论(0编辑  收藏  举报