SparseVector.hh

 class SparseVector
{
private:
//结构体不一定会用到,不用初始化
struct node
{
int index;
int value;
node *next; node(int index, int value, node *next = ) : index(index), value(value), next(next) {}
};
//这些才是真正的数据成员,要初始化的
int size;
node *start; void clear();
void copyList(const SparseVector &sv);
void setNonzeroElem(int index, int value);
void removeElem(int index);
void checkListOrder();
void addSubVector(const SparseVector &sv, bool add);
void removeZeros();
void checkZeros();
public:
SparseVector(int size);
const int getSize()const; ~SparseVector();
SparseVector(const SparseVector &sv);
SparseVector & operator= (const SparseVector &sv);
int getElem(int idx);
void setElem(int index, int value);
bool operator==(const SparseVector &sv)const;
bool operator!=(const SparseVector &sv)const;
SparseVector& operator+=(const SparseVector &sv);
SparseVector& operator-=(const SparseVector &sv);
const SparseVector& operator+(const SparseVector &sv)const;
const SparseVector& operator-(const SparseVector &sv)const;
};

SparseVector.cc

 #include "SparseVector.hh"
#include <cassert>
#include <iostream>
using namespace std;
//单参数构造函数
SparseVector::SparseVector(int size):size(size)
{
start = ;
} const int SparseVector::getSize()const
{
return size;
}
//成员函数都默认带有this指针,所以默认对调用这个函数的对象进行操作,所以不用再传本对象的地址了。
void SparseVector::clear()
{
node *next;
node *current;
current = start;
while(current != )
{
next = current->next;
delete current;
current = next;
}
start = ;
}
//对本对象进行操作,调用成员行数也是默认对本对象进行操作,不用传本对象地址。
SparseVector::~SparseVector()
{
clear();
} void SparseVector::copyList(const SparseVector &sv)
{
size = sv.getSize();
node *current;
node *otherCurrent =sv.start;
node *prev = ; while(otherCurrent != )
{
current = new node(otherCurrent->index, otherCurrent->value);
if(prev == )
{
start = current;
prev = current;
}
prev->next = current;
prev = current;
otherCurrent = otherCurrent->next;
}
} SparseVector::SparseVector(const SparseVector &sv)
{
copyList(sv);
}
//注意自赋值,并且直接调用私有帮助函数。
SparseVector & SparseVector:: operator= (const SparseVector &sv)
{
if (this == &sv)
{
return *this;
}
clear();
copyList(sv);
return *this;
}
//难点
int SparseVector::getElem(int idx)
{
node *current = start;
while(current != && current->index < idx)//过滤,两个条件
{
current = current->next;
}
if(current == )//注意判断条件先后次序,先排除current为0情况
{
return ;
}
else if(current->index == idx)//如果先执行这个,则current为0时,会直接产生段错误
{
return current->value;
}
else
{
return ;
}
}
//难点,分种情况讨论:1,初始为空。2,插到最后面。3,插到最前面。4,插到中间。
void SparseVector::setNonzeroElem(int index, int value)
{
assert(value != );
node *current = start;
node *prev = ; if(start == )//容易遗漏,链表初始为空的情况。(1)
{
start = new node(index, value);
}
else//除此情况外(2,3,4)
{
while(current != && current->index < index)//过滤,两个条件,保证current指向应该指的结点,或其之后的结点。prev指向值小于应该的结点。
{
prev = current;
current = current->next;//别忘了自增
}
/*2选1
* if(current == start)//插到最前面,current所指结点大于等于它
{
if(current->index == index)//等于
{
current->value = value;
}
else//大于
{
node *other = new node(index, value, start);
start = other;
}
}
else if(current == 0)//插到最后面,current所指结点小于它
{
node *other = new node(index, value, 0);
prev->next = other;
}
else//插到中间,current所指结点大于等于它
{
if(current->index == index)//current所指结点等于它
{
current->value = value;
}
else//current所指结点结点大于它
{
node *other = new node(index, value, current);
prev->next = other;
}
}
*/
if(current == )//插到最后边
{
node *other = new node(index, value);
prev->next = other;
}
else if(current -> index == index)//current所指结点等于它的值
{
current->value =value;
}
else if(current == start)//在最开始的地方
{
node *other = new node(index, value, start);
start = other;
}
else //在中间
{
node *other = new node(index, value, current);
prev->next = other;
}
}
} void SparseVector::removeElem(int index)
{
node *current = start;
node *prev = ;
while(current != && current->index < index)//过滤
{
prev = current;
current = current->next;
}
if(current->index == index)//如果是这个结点
{
if(current == start)//是开始结点
{
prev = current;
current = current->next;
delete prev;
start = current;
return;
}
else//是中间结点或者是后边的节点(相同的)
{
prev->next = current->next;
delete current;
return;
}
}
else
{
return;
}
} void SparseVector::setElem(int index, int value)
{
if(value != )
{
setNonzeroElem(index, value);
}
else
{
removeElem(index);
}
} void SparseVector::checkListOrder()
{
node *current = start;
while(current != )
{
cout<<"("<<current->index<<" | "<<current->value<<")"<<endl;
current = current->next;
}
return;
} bool SparseVector::operator==(const SparseVector &sv)const
{
if(size != sv.size)//先判断是不是size不等,直接排除
{
return false;
}
else//每个结点依次判断index和value
{
node *current = start;
node *otherCurrent = sv.start;
while(current != && otherCurrent != )
{
if(current->index != otherCurrent->index || current->value != otherCurrent->value)
{
return false;
}
current = current->next;
otherCurrent = otherCurrent->next;
}
if(current == && otherCurrent == )//看看还有没有哪个剩余结点
{
return true;
}
else
{
return false;
}
}
} bool SparseVector::operator!=(const SparseVector &sv)const
{
return !(*this == sv);//调用等号,结果取反
} void SparseVector::addSubVector(const SparseVector &sv, bool add)
{
node *current = start;
node *otherCurrent = sv.start;
node *prev = ;
int sign = (add ? : -);//注意符号处理方式 if(current == )//两个链表合并时,一定不能忽略被合并链表为空的情况:(a+=b,其中a为空)
{
if(otherCurrent == )//(ab均为空)
{
return;
}
else
{
while(otherCurrent != )//(a为空b不为空)参考直接插入法形成一个新链表
{
node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, );
if(prev == )
{
start = addTo;
prev = addTo;
current = addTo;
}
else
{
current->next = addTo;
current = addTo;
}
otherCurrent = otherCurrent->next;
}
return;
}
}
else//合并时均非空的情况
{
while(current != && otherCurrent != )//都顺序遍历,直到某一链表结束
{
if(current->index > otherCurrent->index)//插入的
{
if(prev == )//初始结点
{
node *addTo = new node (otherCurrent->index, sign * otherCurrent->value, current);
start = addTo;
prev = addTo;
otherCurrent = otherCurrent->next;
}
else//非初始结点
{
node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current);
prev->next = addTo;
prev = addTo;
otherCurrent = otherCurrent->next;
}
}
else if(current->index == otherCurrent->index)//直接加减的
{
current->value += sign * otherCurrent->value;
prev = current;
current = current->next;
otherCurrent = otherCurrent->next;
}
else if(current->index < otherCurrent->index)//不插入的
{
prev = current;
current = current->next;
}
}
if(otherCurrent == )//处理剩余的结点
{
return;
}
else//把剩余的插入到原来的
{
while(otherCurrent != )
{
node *addTo = new node(otherCurrent->index, sign * otherCurrent->value, current);
prev->next = addTo;
prev = addTo;
otherCurrent = otherCurrent->next;
}
}
return;
}
} void SparseVector::removeZeros()
{
node *current = start;
node *prev = ;
while(current != )//非0状态
{
if(current->value != )
{
prev = current;
current = current->next;
}
else//为0状态
{
if(prev == )//如果初始结点为0
{
prev = current;
current = current->next;
delete prev;
start = current;
prev = ;
}
else//非初始结点为0
{
node *temp = current;
current = current->next;
delete temp;
prev->next = current;
}
}
}
} SparseVector& SparseVector::operator+=(const SparseVector &sv)
{
addSubVector(sv, true);
removeZeros();
node * current = start;
size = ;
while(current != )//最后还要把size弄好
{
++size;
current = current->next;
}
return *this;
} SparseVector& SparseVector::operator-=(const SparseVector &sv)
{
addSubVector(sv, false);
removeZeros();
size = ;
node *current = start;
while(current != )//最后还要把size弄好
{
++size;
current = current->next;
}
return *this;
} const SparseVector& SparseVector::operator+(const SparseVector &sv)const
{
SparseVector *newSp = new SparseVector(*this);
*newSp += sv;
return *newSp;
} const SparseVector& SparseVector::operator-(const SparseVector &sv)const
{
SparseVector *newSp = new SparseVector(*this);
*newSp -= sv;
return *newSp;
} void SparseVector::checkZeros()
{
node *current = start;
while(current != )
{
if(current->value == )
{
cout<<"number "<<current->index<<" "<<current->value<<endl;
current = current->next;
}
}
}

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. Ret2Libc 练习(2) -- VirtualProtect

    这几天做了NSCTF和GCTF,耽误了几天,今天继续. 这次绕过DEP的方法是利用VirtualProtect函数将shellcode所在的内存属性改成可执行状态就可以绕过DEP了. 首先看一下Vir ...

  2. C#压缩图片——高质量压缩方式

    传入Bitmap对象,以及新图片的长宽(Bitmap.Size),这样生成的就是跟原图尺寸一致的低质量图片 public Bitmap GetImageThumb(Bitmap mg, Size ne ...

  3. kbengine里如何使用git快速下载项目?

    项目有两个镜像,github[https://github.com/kbengine/kbengine.git] ,osc开源中国[https://git.oschina.net/likecg/kbe ...

  4. 用Join子句进行分组联接

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  5. 移动支持 – ASP.NET MVC 4 系列

           目前,有各种各样的方法可以提高网站应用程序的移动体验.在某些情况下,我们只想在小规格上做一些微小的风格变化:另一些情况下,我们可能完全改变外观显示或者一些视图的内容:最极端的情况下,我们 ...

  6. 表单和 HTML 辅助方法– ASP.NET MVC 4 系列

           这里有一个疑问,诸如在文本编辑器中输入 HTML 元素如此简单的任务,也需要任何帮助吗?的确,输入标签名称是很容易的事,但是确保 HTML 页面链接中的 URL 指向正确的位置.表单元素 ...

  7. memcache原理、简单使用、分布式实现方案

    原理:http://www.cnblogs.com/chy2055/p/5127499.html 使用教程:http://www.travisup.com/post/index/21 memcache ...

  8. 【深度学习】之Caffe的solver文件配置(转载自csdn)

    原文: http://blog.csdn.net/czp0322/article/details/52161759 今天在做FCN实验的时候,发现solver.prototxt文件一直用的都是mode ...

  9. WebBrowser处理AJAX生成的网页内容!

    WebBrowser处理AJAX生成的网页内容! 等待网页执行完毕(AJAX执行后). 使用webBrowser1.Document.Body.OuterHtml可以获取到AJAX产生的网页内容.

  10. 别再为了this发愁了------JS中的this机制

    别再为了this发愁了------JS中的this机制 题记:JavaScript中有很多令人困惑的地方,或者叫做机制.但是,就是这些东西让JavaScript显得那么美好而与众不同.比方说函数也是对 ...