cs11_c++_lab4b
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的更多相关文章
- cs11_c++_lab7
wcount.cc #include <iostream> #include <map> #include <string> #include <algori ...
- cs11_c++_lab6
expressions.hh #ifndef EXPRESSIONS_HH #define EXPRESSIONS_HH #include "environment.hh" #in ...
- cs11_c++_lab5待修改
heap.hh #ifndef HEAP_HH #define HEAP_HH #include <iostream> #include <stdexcept> #includ ...
- cs11_c++_lab4a
SparseVector.hh class SparseVector { private: //结构体不一定会用到,不用初始化 struct node { int index; int value; ...
- cs11_c++_lab3
Matrix.hh class Matrix { int row; int col; int *p; void copy(const Matrix &m); void clearup(); p ...
- cs11_c++_lab2
Matrix.hh class Matrix { int row; int col; int *p; public: Matrix(); Matrix(int x,int y); ~Matrix(); ...
- cs11_c++_lab1
lab1.cpp #include "Point.hh" #include <iostream> #include <cmath> using namesp ...
随机推荐
- ACM water
1000 纯属适应题 1003 做的时候花了很久,现在看好像也不难 1004 适应题,求下平均就行 1005 要读懂题就行 1007 逆序数,discuss方法 1046 全部暴搜一遍.. ...
- 转载:Qt之界面实现技巧
总结一下,在开发Qt的过程中的一些技巧!可遇而不可求... 一.主界面 1.窗口 最小化 最大化 关闭按钮.显示状态自定义 setWindowFlags(Qt::CustomizeWindowHint ...
- 将应用部署到Tomcat根目录的方法 去掉url里的项目名
在"conf/Catalina/localhost"目录下增加新的文件"ROOT.xml"(注意大小写哦),文件内容如下: <?xml version=& ...
- TOMCAT 无法安装P7B格式的证书
背景:通过按以下链接的方式生成了CSR文件,并申请到P7B格式的证书 现象:TOMCAT安装该证书时,要求输入Keystore key, 但是P7B证书自身并不携带私钥.导致无法通过TOMCAT安装该 ...
- 经验分享:Linux 双网卡SNAT和DNAT映射本地端口出外网
A 机器 网卡1 公网IP网卡2 内网 B 机器网卡1 内网 如果想把公网端口P1 映射为内网B机器端口P2 iptables -t nat -A PREROUTING -d [A公网地址] -p ...
- selenium浏览器操作
在元素定位中xpath使用的还算比较多,介绍一下常见的firfox和chrome浏览器插件安装 一.浏览器定位工具安装 1.firfox firfox比较简单,主要浏览器自带的定位功能也比较强大国内也 ...
- 分析案例:应用服务器W3WP进程CPU持续超过百分之九十(Oracle客户端Bug)
问题描述: 项目反馈应用负载的其中一台服务器业务操作的响应非常慢,登录该服务器发现W3WP进程CPU持续超过90%,哪怕在业务低峰期也是如此?远程查看后发现该应用服务器承载的请求确实很低,why??? ...
- 【性能诊断】StackOverflow引发的“网络”及系统稳定性问题
背景描述: 最近一个项目的系统管理员和业务运维人员分别反馈问题: 1.应用系统每个月会有一两次宕机,需要管理员手工重启IIS: 2.财务模块一个功能经常报网络错误“网络异常,请检查网络连接”“Unab ...
- C++中vector的用法
C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现.容器向量也是一个类模板.标准库vector类型使用需要的头 ...
- php ffmpeg
可以合成视频,音频视频合成等 $aurl = '../Uploads/movie/zzz.mp4'; $vurl = '../Uploads/mp3/dmd.mp3'; // exec("c ...