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 = ) : 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. };

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 = ;
  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 != )
  22. {
  23. next = current->next;
  24. delete current;
  25. current = next;
  26. }
  27. start = ;
  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 = ;
  41.  
  42. while(otherCurrent != )
  43. {
  44. current = new node(otherCurrent->index, otherCurrent->value);
  45. if(prev == )
  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 != && current->index < idx)//过滤,两个条件
  76. {
  77. current = current->next;
  78. }
  79. if(current == )//注意判断条件先后次序,先排除current为0情况
  80. {
  81. return ;
  82. }
  83. else if(current->index == idx)//如果先执行这个,则current为0时,会直接产生段错误
  84. {
  85. return current->value;
  86. }
  87. else
  88. {
  89. return ;
  90. }
  91. }
  92. //难点,分种情况讨论:1,初始为空。2,插到最后面。3,插到最前面。4,插到中间。
  93. void SparseVector::setNonzeroElem(int index, int value)
  94. {
  95. assert(value != );
  96. node *current = start;
  97. node *prev = ;
  98.  
  99. if(start == )//容易遗漏,链表初始为空的情况。(1)
  100. {
  101. start = new node(index, value);
  102. }
  103. else//除此情况外(2,3,4)
  104. {
  105. while(current != && 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 == )//插到最后边
  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 = ;
  167. while(current != && 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 != )
  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 != )
  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 != && otherCurrent != )
  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 == && otherCurrent == )//看看还有没有哪个剩余结点
  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 = ;
  258. int sign = (add ? : -);//注意符号处理方式
  259.  
  260. if(current == )//两个链表合并时,一定不能忽略被合并链表为空的情况:(a+=b,其中a为空)
  261. {
  262. if(otherCurrent == )//(ab均为空)
  263. {
  264. return;
  265. }
  266. else
  267. {
  268. while(otherCurrent != )//(a为空b不为空)参考直接插入法形成一个新链表
  269. {
  270. node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, );
  271. if(prev == )
  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 != && otherCurrent != )//都顺序遍历,直到某一链表结束
  290. {
  291. if(current->index > otherCurrent->index)//插入的
  292. {
  293. if(prev == )//初始结点
  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 == )//处理剩余的结点
  322. {
  323. return;
  324. }
  325. else//把剩余的插入到原来的
  326. {
  327. while(otherCurrent != )
  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 = ;
  343. while(current != )//非0状态
  344. {
  345. if(current->value != )
  346. {
  347. prev = current;
  348. current = current->next;
  349. }
  350. else//为0状态
  351. {
  352. if(prev == )//如果初始结点为0
  353. {
  354. prev = current;
  355. current = current->next;
  356. delete prev;
  357. start = current;
  358. prev = ;
  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 = ;
  377. while(current != )//最后还要把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 = ;
  390. node *current = start;
  391. while(current != )//最后还要把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 != )
  417. {
  418. if(current->value == )
  419. {
  420. cout<<"number "<<current->index<<" "<<current->value<<endl;
  421. current = current->next;
  422. }
  423. }
  424. }

cs11_c++_lab4b的更多相关文章

  1. cs11_c++_lab7

    wcount.cc #include <iostream> #include <map> #include <string> #include <algori ...

  2. cs11_c++_lab6

    expressions.hh #ifndef EXPRESSIONS_HH #define EXPRESSIONS_HH #include "environment.hh" #in ...

  3. cs11_c++_lab5待修改

    heap.hh #ifndef HEAP_HH #define HEAP_HH #include <iostream> #include <stdexcept> #includ ...

  4. cs11_c++_lab4a

    SparseVector.hh class SparseVector { private: //结构体不一定会用到,不用初始化 struct node { int index; int value; ...

  5. cs11_c++_lab3

    Matrix.hh class Matrix { int row; int col; int *p; void copy(const Matrix &m); void clearup(); p ...

  6. cs11_c++_lab2

    Matrix.hh class Matrix { int row; int col; int *p; public: Matrix(); Matrix(int x,int y); ~Matrix(); ...

  7. cs11_c++_lab1

    lab1.cpp #include "Point.hh" #include <iostream> #include <cmath> using namesp ...

随机推荐

  1. JS在路径中传中文参数

    需要用 encodeURI('中文');处理一下.

  2. wiseinstall 制做安装包小记

    好久没写博客了..昨天未来的自己给自己托了个梦,说以后你肯定会忘了你今天白天是怎么制做安装包的,所以又来记录了..希望以后可以保持这个好习惯. 程序安装完后,可执行程序是 Wise32.exe 第一步 ...

  3. linux-3.0内核移植到fl2440开发板(以MINI2440为模板)

    我们的fl2440开发板使用的是s3c2440的芯片,与MINI2440十分相似,因此需要改动的地方不多,移植也比较容易. 1.[weishusheng@localhost kernel]$ sudo ...

  4. Yii2 利用controllerMap自定义控制器类

    版权声明:本文为博主原创文章,未经博主允许不得转载. Yii2框架为我们自定义好的  controllers,Models,views,标准的MVC结构框架,但是有些时候我们写接口希望结构更加清晰而不 ...

  5. 游戏AI框架

  6. 使用npm安装一些包失败了的看过来(npm国内镜像介绍)

    这个也是网上搜的,亲自试过,非常好用! 镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在): 1.通过config命令 npm config set reg ...

  7. ubuntu安装php5.3

    sudo -i wget http://in1.php.net/distributions/php-5.3.29.tar.bz2 .tar.bz2 cd php- apt-get install li ...

  8. Digests from CG articales

    Turtle Talk Prior to the on-set motion capture, the team had the actors perform expressions while be ...

  9. linux使用secureCRT连接(没有rsa的时候)

    一台linux新机器,怎么使用secureCRT连接呢??? 首先  vim   /etc/sysconfig/network-scripts/ifcfg-eth0 把BOOTPROTO=none I ...

  10. Java借助Runtime调用外部程序阻塞的代码

    有时候在java代码中会调用一些外部程序,比如SwfTools来转换swf.ffmpeg来转换视频等.如果你的代码这样写:Runtime.getRuntime().exec(command),会发现程 ...