#include<iostream>
#include<stdio.h>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cassert>
using namespace std;
template <class T> class JaggedArray
{
//---------模板变量定义------------
int num_Elements;
//元素个数
int num_Bins;
//箱子个数
/*-------unpacked-------*/
int* counts;
//容器的存储情况
T** unpacked_values;
//未打包数值
/*------unpacked_end--------*/
/*------packed--------------*/
int* offsets;
//容器的存储情况
T* packed_values;
//打包数值
/*------packed_end---------*/
//-----------模板变量定义end----------
//-----------函数定义-----------------
public:
JaggedArray(int Size);
void addElement(int Bin_num,T element);
bool isPacked();
T getElement(int Bin_num ,int element_num);
int numBins();
int numElements();
void print();
int numElementsInBin(int Bin_num);
void pack();
void unpack();
void removeElement(int Bin_num , int Element_position);
void clear();
//-----------函数定义end---------
};
template <class T> JaggedArray<T>:: JaggedArray(int Size)
{
/**
*构造函数
*Size表示容器的数量
*/
int n;
//n用来进行数组的初始化
num_Bins = Size;
num_Elements = 0;
counts = (int*) malloc (Size*sizeof(int));
for(n=0;n<Size;n++)
{
counts[n]=0;
}
//容器数量初始化
unpacked_values = (T**) malloc(Size*sizeof(T*));
for(n=0;n<Size;n++)
{
unpacked_values[n] = NULL;
}
//容器内部初始化
offsets = NULL;
packed_values = NULL;
//将packed内容初始化为null
}
//-------------增加元素的函数-------------------------------------------
template <class T> void JaggedArray<T>::addElement(int Bin_num,T element)
{
/**
*Bin_num 增添元素的容器编号
*element 要增添的元素
*/
//int now_num = this.counts[Bin_num];
if(isPacked()==false)
{
unpacked_values[Bin_num] = (T*)realloc(unpacked_values[Bin_num],sizeof(T)*(counts[Bin_num]+1));
//申请更多的内存空间
unpacked_values[Bin_num][counts[Bin_num]]=element;
//将需要添加的元素填入
counts[Bin_num]++;
//容器中元素数量+1
num_Elements++;
//总的元素数量+1
}
else
exit(1);
}
template <class T> bool JaggedArray<T>::isPacked()
{
/**
*判定是否是打包类型的函数
*/
if(offsets==NULL&&packed_values==NULL)
return false;
//满足打包类型的条件,返回true
else
return true;
}
template<class T> T JaggedArray<T>::getElement(int Bin_num ,int element_num)
{
/**
*获得元素函数
*Bin_num 要获得元素所在的容器
*element_num 要获得元素的位置
*/
if(element_num < 0 && Bin_num >= num_Bins)
exit(1);
//输入越界,退出
if(isPacked() == false)
//当前类型为未打包类型时
{
if(element_num < counts[Bin_num])
return unpacked_values[Bin_num][element_num];
//如果元素存在,返回该元素
else
exit(1);
}
else
//当前类型为打包类型时
{
if(element_num < numElementsInBin(Bin_num))
return packed_values[offsets[Bin_num]+element_num];
//如果元素存在,返回该元素
else
exit(1);
}
}
template<class T> int JaggedArray<T>::numBins()
{
/**
*返回容器数量的函数
*/
return num_Bins;
}
template<class T> int JaggedArray<T>::numElementsInBin(int Bin_num)
{
/**
*返回容器内元素个数的函数
*Bin_num 容器的编号
*/
if(Bin_num >= num_Bins || Bin_num < 0)
exit(1);
//输入越界,结束
if(isPacked() == true)
//如果当前是打包类型
{
if(Bin_num == (num_Bins-1))
//如果是最后一个容器
return num_Elements - offsets[Bin_num];
else
//不是最后一个容器
return offsets[Bin_num+1] - offsets[Bin_num];
}
else
//如果当前不是打包类型
{
return counts[Bin_num];
}
}
template<class T> int JaggedArray<T>::numElements()
{
/**
*返回元素个数的函数
*/
return num_Elements;
}
template<class T> void JaggedArray<T>::unpack()
{
/**
*将apcked类型转化为unpacked类型
*/
if(isPacked() == false)
return;
//如果已经是unpack类型,直接返回
counts = (int*) malloc(num_Bins*sizeof(int));
int value = num_Elements;
for(int i = num_Bins-1;i >= 0;i--)
{
counts[i] = value - offsets[i];
value = value - counts[i];
}
//对counts进行初始化
unpacked_values = (T**) malloc(num_Bins*sizeof(T*));
for(int i = 0,Bin_num = 0;Bin_num < num_Bins && i < num_Elements;Bin_num++)
{
int numInBin = numElementsInBin(Bin_num);
if(numInBin > 0)
{
unpacked_values[Bin_num] = (T*) malloc(numInBin*sizeof(T));
for(int j = 0;j < numInBin;j++)
{
unpacked_values[Bin_num][j] = packed_values[i];
i++;
}
}
}
free(offsets); offsets = NULL;
free(packed_values); packed_values = NULL;
}
template<class T> void JaggedArray<T>::pack()
{
/**
*将unapcked类型转化为packed类型
*/
if(isPacked())
return;
//如果已经是转化类型,直接结束函数
offsets = (int*) malloc(num_Bins*sizeof(int));
int value = num_Elements;
for(int i = num_Bins-1;i >= 0;i--)
{
offsets[i] = value - counts[i];
value = value - counts[i];
}
//对offsets进行初始化
packed_values = (T*) malloc(num_Elements*sizeof(T));
for(int Bin_num = 0,i = 0;Bin_num < num_Bins && i < num_Elements;Bin_num++)
//Bin_num 指向unpacked类型对应的容器
//i 指向packed_values对应的单元
{
int numInBin = numElementsInBin(Bin_num);
if(numInBin>0)
//单元中有元素存在
{
for(int j = 0;j < numInBin;j++)
{
packed_values[i] = unpacked_values[Bin_num][j];
i++;
//存储结果,向后移动一位
}
}
}
//对packed_values进行初始化
free(counts); counts = NULL;
free(unpacked_values); unpacked_values = NULL;
//对类型进行更改
}
template<class T>void JaggedArray<T>:: removeElement(int Bin_num,int Element_position)
{
/**
*删除函数
*Bin_num 元素所在容器编号
*Element_position 元素位置
*/
T* temp;
//temp为中间值
int temp_position,n;
if(isPacked()==false)
//数据合理条件?
{
if(counts[Bin_num]==1)
//从只有一个元素的容器中进行删除
{
free(unpacked_values[Bin_num]);
unpacked_values[Bin_num]=NULL;
counts[Bin_num]=0;
num_Elements--;
}
else
//从大于一个元素的容器中进行删除
{
temp=(T*)malloc(sizeof(T)*(counts[Bin_num]-1));
//分配空间
for(temp_position=0,n=0;n<counts[Bin_num];n++)
{
if(n!=Element_position)
//跳过要删除的元素
{
temp[temp_position]=unpacked_values[Bin_num][n];
temp_position++;
}
}
//赋值循环
free(unpacked_values[Bin_num]);
unpacked_values[Bin_num]=temp;
counts[Bin_num]--;
num_Elements--;
}
}
else
exit(1);
}
template<class T> void JaggedArray<T>::print()
{
/**
*输出函数
*/
if(isPacked())
//判断类型
{
cout<<"packed JaggedArray"<<endl;
cout<<" num_bins:"<<num_Bins<<endl;
cout<<" num_elements"<<num_Elements<<endl;
cout<<" offsets:";
for(int temp = 0;temp < num_Bins;temp++)
{
cout<<offsets[temp]<<" ";
}
cout<<endl;
//输出容器内元素个数
cout<<" values:";
for(int temp = 0;temp < num_Elements;temp++)
{
cout<<packed_values[temp]<<" ";
}
cout<<endl;
//输出元素值
}
else
{
cout<<"unpacked JaggedArray"<<endl;
cout<<" num_bins:"<<num_Bins<<endl;
cout<<" num_elements"<<num_Elements<<endl;
cout<<" counts:";
for(int temp = 0;temp < num_Bins;temp++)
{
cout<<" "<<counts[temp];
}
cout<<endl;
//输出容器内元素个数
cout<<" values:";
for(int element_num = 0,line_num = 0;element_num < num_Elements;)
//element_num计数已经输出元素个数
//line_num当前输出的行数,也表示元素在容器内的位置
{
if(line_num != 0)
{
cout<<" ";
//若不是第一行,为保持格式,输出一定数量的空格(9个)
}
for(int Bin_num = 0;Bin_num < num_Bins;Bin_num++)
{
if(numElementsInBin(Bin_num) <= line_num)
cout<<" ";
//当容器在本行没有元素的时候(2个)
else
{
cout<<" "<<unpacked_values[Bin_num][line_num];
element_num++;
}
}
line_num++;
cout<<endl;
}
//输出元素值
}
}
template<class T> void JaggedArray<T>::clear()
{
/**
*删除函数
*/
for(int Bin_num = 0;Bin_num < num_Bins;Bin_num++)
{
counts[Bin_num] = 0;
free(unpacked_values[Bin_num]);
unpacked_values[Bin_num] = NULL;
//将容器内存释放,指向NULL
}
num_Elements = 0;
//元素数量置0
}