这个想法来自于数组链表,在数组链表中,数组的每一个元素对应一个指针,这个指针是下一个元素的index。用整数表示指针。

这是这个vector的源码:

 #include <iostream>
using std::cout; template <typename T>
class Vector
{
private:
int m_block,m_size,m_asize;
int *ip,*rip;//ip:actual->visual;rip:v->a
T *tp;
void brushrip();
int partition(int,int);
void qsort(int,int); public:
Vector(int block=):m_block(block),m_asize(),m_size(),rip(NULL),ip(NULL),tp(NULL){}
// Vector(const Vector<T>& v,int block=100);
int size() const{return m_size;}
bool insert(const T& t,int pos=-,int num=);
bool erase(int pos);
bool erase(int pos,int num);
// bool thin();
T& operator[](const int key)const;
bool recover(const int const*);
int* getorder() const;
void sort();
void swap(int pos1,int pos2);
};
template <typename T>
void Vector<T>::swap(int pos1,int pos2)
{ ip[rip[pos1]]=pos2;
ip[rip[pos2]]=pos1;
int ac1=rip[pos1],ac2=rip[pos2];
rip[ip[ac1]]=ac1;
rip[ip[ac2]]=ac2;
} template <typename T>
void Vector<T>::sort()
{
qsort(,m_size-);
}
template <typename T>
void Vector<T>::qsort(int p,int r)
{
if(p<r)
{
int q=partition(p,r);
qsort(p,q-);
qsort(q+,r);
}
}
template <typename T>
int Vector<T>::partition(int p,int r)
{
T& x=tp[rip[r]];
int i=p-;
for(int j=p;j<=r-;j++)
{
if(tp[rip[j]]<x)
{
i++;
if(i!=j)swap(i,j);
}
}
if(r!=i+)swap(i+,r);
return i+;
}
template <typename T>
int* Vector<T>::getorder() const
{
if(m_size==)return NULL;
int *p=new int[m_size];
for(int i=;i<m_size;i++)p[i]=ip[i];
return p;
} template <typename T>
bool Vector<T>::recover(const int* p)
{
// if((sizeof(p)/sizeof(int))<m_size)return false;
for(int i=;i<m_size && p[i]<m_size && p[i]>=;i++)ip[i]=p[i];
brushrip();
return true;
} template <typename T>
void Vector<T>::brushrip()
{
if(m_size==){delete[] rip;rip=NULL;return;}
if(sizeof(rip)/sizeof(int)!=m_size)
{delete[] rip;rip=NULL;rip=new int[m_size];}
for(int i=;i<m_size;i++){rip[ip[i]]=i;}
} template <typename T>
bool Vector<T>::insert(const T& t,int pos,int num)
{
if(pos<)pos=m_size+pos+;
if(pos< || pos>m_size)return false;
int newblock=(m_size+num-m_asize)/m_block+;
if(newblock>)
{
m_asize+=newblock*m_block;
int *ipp=new int[m_asize];
T *tpp=new T[m_asize];
for(int i=;i<m_size;i++){tpp[i]=tp[i];ipp[i]=ip[i];}
delete[] tp;delete[] ip;
tp=tpp;ip=ipp;
}
for(int i=;i<m_size;i++)if(ip[i]>=pos)ip[i]=ip[i]+num;
for( i=;i<num;i++) {ip[i+m_size]=pos+i;tp[i+m_size]=t;}
m_size+=num;
brushrip();
return true;
} template <typename T>
bool Vector<T>::erase(int pos)
{
if( pos< || pos>=m_size)return false;
m_size--;
if(rip[pos]!=m_size)
{
T temp=tp[rip[pos]];
tp[rip[pos]]=tp[m_size];
tp[m_size]=temp;
ip[rip[pos]]=ip[m_size];
}
for(int i=;i<m_size;i++)if(ip[i]>pos)ip[i]--;
brushrip();
return true;
}
template <typename T>
bool Vector<T>::erase(int pos,int num)
{
for(int i=;i<num;i++)if(!erase(pos))return false;
return true;
} template <typename T>
T& Vector<T>::operator[](const int key)const
{
return tp[rip[key]];
} int main()
{
Vector<int> v;
v.insert(,,);
v.insert(,,);
v.insert(,,);
v.erase(,);
v.insert(,,);
v.swap(,);
cout<<"排序前:\n";
for(int i=;i<v.size();i++)cout<<v[i]<<" ";
int *p=v.getorder();
v.sort();cout<<"\n排序后:\n";
for( i=;i<v.size();i++)cout<<v[i]<<" ";
if(v.recover(p))cout<<"\n复原:\n";
for( i=;i<v.size();i++)cout<<v[i]<<" ";
cout<<"\n";
delete[] p; return ;
}

实现了operator[],快排,getorder,recover,insert,erase

内存的组织形式是这样的:

1.动态顺序存储,insert总将数据存储到顺序表的尾部。

2.另有有整型数组ip,与顺序表同长,建立数据存储的实际位置与表象未知的函数

3.数据交换的操作就不再直接操作数据本身,而是操作 数组ip

4.可以用getorder记录下数组ip,以后就可以用recover回复到这个状态了

也就是说,数据一旦被存储,他的实际位置就不再变了,变的只是 数组ip。而数组ip可以记录成不同的状态,所以这个vector可以用来做版本管理。

c++ 能够记录状态的vector的更多相关文章

  1. 2014 网选 广州赛区 hdu 5025 Saving Tang Monk(bfs+四维数组记录状态)

    /* 这是我做过的一道新类型的搜索题!从来没想过用四维数组记录状态! 以前做过的都是用二维的!自己的四维还是太狭隘了..... 题意:悟空救师傅 ! 在救师父之前要先把所有的钥匙找到! 每种钥匙有 k ...

  2. hiho #1474 拆字游戏(dfs,记录状态)

    #1474 : 拆字游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Kui喜欢把别人的名字拆开来,比如“螺”就可以拆成“虫田糸”,小Kui的语文学的不是很好,于是 ...

  3. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  4. Oracle EBS FORM 更改记录状态

    get到一个新的思路. 因为validate触发器是无法做go_block或者loop操作的,因此可以尝试修改数据块属性,将状态更新为改动的,触发 ON-UPDATE 触发器,将循环或者跳转语句加入到 ...

  5. hdu4528 小明系列故事——捉迷藏(记录状态的BFS)题解

    思路: 一道BFS题,和以前的BFS有点不同,这里的vis数组需要记录每次走时的状态,所以开了3维,只对该状态下的vis修改. 注意坑点:S的位置是可以走的 代码: #include<queue ...

  6. Vue学习记录-状态管理

    要解决的问题 平时的系统开发中,基本都会碰到这个权限问题,需要根据用户的登录状态进行处理.最常见的情况就是“先登录,后使用”.除去打包成APP,无法看到连接外,如果地址栏里直接输入地址就能绕过登录的话 ...

  7. POJ-1703 Find them, Catch them(并查集&数组记录状态)

    题目: The police office in Tadu City decides to say ends to the chaos, as launch actions to root up th ...

  8. flask用session记录状态

    html <form action="/login" method="POST"> <input type="text" ...

  9. 动态规划:HDU1160-FatMouse's Speed(记录动态规划状态转移过程)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

随机推荐

  1. $_SERVER 的用法

    PHP编程中经常需要用到一些服务器的一些资料,特把$_SERVER的详细参数整理下,方便以后使用. $_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root ...

  2. css3多列样式

  3. PHP中curl的CURLOPT_POSTFIELDS参数使用细节

    CURL确实是一个不错的好工具,不仅在PHP中还是其他的操作系统中,都是一个非常好用的.但是如果你有些参数没有用好的话,那可能会得不到自己理想中的结果. 在通常情况下,我们使用 CURL 来提交 PO ...

  4. Spring中集合类型属性注入

    我们都知道如何去注入普通属性的值,非常简单,那么我们如何去注入开发中常见的集合类型的属性了,别急,往下看. 这里将介绍如何给Map list set Array Properties 这些属性注入值. ...

  5. Node.js与Express4安装与配置

    Nodejs简介 Node.js 基于 Chrome JavaScript 运行环境,用于便捷地搭建快速.可扩展的网络应用. 它使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效, 非常适合 ...

  6. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  7. Linux 架构

    (转)作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! http://www.cnblogs.com/vamei/archive/2 ...

  8. hdu 1501 Zipper

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1501 思路:题目要求第三个串由前两个组成,且顺序不能够打乱,搜索大法好 #include<cstdi ...

  9. hdu 1358 Period

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1358 思路:Next数组的用法,在第i个位置上如果有i%(i-Next[i])==0的话最小循环节就是 ...

  10. AngularJS HTML DOM

    AngularJS 为 HTML DOM 元素的属性提供了绑定应用数据的指令. ng-disabled 指令: ng-disabled 指令直接绑定应用程序数据到 HTML 的 disabled 属性 ...