您的位置:首页 > 编程语言 > Delphi

VC++实现的类似Delphi的TStringList对象列表类

2011-03-25 10:12 483 查看
// 头文件:MyStringList.h

//////////////////////////////////////////////////////////////
//1、简 介:对象列表类 - 索引串+对象指针
//2、主要功能:
//
// 可以根据索引串活对象指针值获取索引
// 灵活添加删除
//
//
//////////////////////////////////////////////////////////////
#ifndef Define_CStringList_
#define Define_CStringList_

struct ListItem
{
char *Key; //索引串
int Len; //字节数
LPVOID obj; //对象指针

int KeyIndex; //索引组中索引
int ObjIndex; //对象组中索引
int OrgIndex; //原始组中索引

ListItem()
{
Key = NULL;
Len = 0;
obj = NULL;
KeyIndex = -1;
OrgIndex = -1;
ObjIndex = -1;
}
};
typedef ListItem * pListItem;

class CMyStringList: public CObject
{
private:
CObArray lstKey;
CObArray lstOrg;
CObArray lstObj;

void Insert_KeyLst(ListItem *p,int LowIndex,int HighIndex);
void Insert_ObjLst(ListItem *p,int LowIndex,int HighIndex);
int GetKeyIndex(char *p,int LowIndex,int HighIndex);
int GetObjIndex(LPVOID obj,int LowIndex,int HighIndex);
public:
~CMyStringList();

void Add(CString &key,LPVOID obj);
void Add(LPVOID obj);
void Add(CString &key);

void InsertAt(int Index,CString &key,LPVOID obj);
void InsertAt(int Index,LPVOID obj);
void InsertAt(int Index,CString &key);

int IndexOf(CString &key);
int IndexOf(LPVOID obj);

void Delete(CString &key);
void Delete(LPVOID obj);
void Delete(int Index);

int GetSize();

LPVOID ElementAt_Obj(int Index);
LPVOID ElementAt_Key(int Index);

void RemoveAll();
};

#endif

// CPP文件:MyStringList.cpp
/////////////////////////////////////////////////
//
// VC++实现的对象列表 索引串 :对象指针
//
/////////////////////////////////////////////////
#include "StdAfx.h"
#include "MyStringList.h"

void CStringToPChar(CString &str,char **p,int &Len)
{
Len = str.GetLength()+1;
*p = new char[Len];
::ZeroMemory(*p,Len);
strcpy(*p,str);
};

void CMyStringList::Insert_KeyLst(ListItem *p,int LowIndex,int HighIndex)
{
pListItem pComp;

if (lstKey.GetSize()==0)
{
lstKey.Add((CObject *)p);
p->KeyIndex = 0;
return;
}

if (LowIndex == HighIndex)
{
pComp = (pListItem)lstKey.ElementAt(LowIndex);
if (strcmp(p->Key,pComp->Key) < 0)
{
lstKey.InsertAt(LowIndex,(CObject *)p);
p->KeyIndex = LowIndex;
}
else
{
int iInsert = LowIndex + 1;
if (iInsert >= lstKey.GetSize())
lstKey.Add((CObject *)p);
else
lstKey.InsertAt(iInsert,(CObject *)p);
p->KeyIndex = iInsert;
}
return;
}

//二分法比较
int iMiddle = (LowIndex + HighIndex)/2;
iMiddle = (iMiddle < 0)?0:iMiddle;
pComp = (pListItem)lstKey.ElementAt(iMiddle);
if (strcmp(p->Key,pComp->Key) < 0)
Insert_KeyLst(p,LowIndex,((iMiddle-1)<0?0:(iMiddle-1)));
else
Insert_KeyLst(p,iMiddle+1,HighIndex);
}

void CMyStringList::Insert_ObjLst(ListItem *p,int LowIndex,int HighIndex)
{
pListItem pComp;

if (lstObj.GetSize()==0)
{
lstObj.Add((CObject *)p);
p->ObjIndex = 0;
return;
}

if (LowIndex == HighIndex)
{
pComp = (pListItem)lstObj.ElementAt(LowIndex);
if ((int)p->obj < (int)pComp->obj)
{
lstObj.InsertAt(LowIndex,(CObject *)p);
p->ObjIndex = LowIndex;
}
else
{
int iInsert = LowIndex + 1;
if (iInsert >= lstObj.GetSize())
lstObj.Add((CObject *)p);
else
lstObj.InsertAt(iInsert,(CObject *)p);
p->ObjIndex = iInsert;
}
return;
}

//二分法比较
int iMiddle = (LowIndex + HighIndex)/2;
iMiddle = (iMiddle < 0)?0:iMiddle;
pComp = (pListItem)lstObj.ElementAt(iMiddle);
if ((int)p->obj < (int)pComp->obj)
Insert_ObjLst(p,LowIndex,((iMiddle-1)<0?0:(iMiddle-1)));
else
Insert_ObjLst(p,iMiddle+1,HighIndex);
}

CMyStringList::~CMyStringList()
{
RemoveAll();
}

void CMyStringList::InsertAt(int Index,LPVOID obj)
{
CString c="";
InsertAt(Index,c,obj);
}

void CMyStringList::InsertAt(int Index,CString &key)
{
InsertAt(Index,key,NULL);
}

void CMyStringList::InsertAt(int Index,CString &key,LPVOID obj)
{
CString s;
pListItem p = new ListItem();
CStringToPChar(key,&p->Key,p->Len);
p->obj = obj;
p->OrgIndex = Index;
lstOrg.InsertAt(Index,(CObject *)p);

Insert_KeyLst(p,0,lstKey.GetSize()-1);
Insert_ObjLst(p,0,lstObj.GetSize()-1);

//调整各列表索引号
int iKey = p->KeyIndex;
int iObj = p->ObjIndex;
for(int j=iKey+1;j<lstKey.GetSize();j++)
{
p = (pListItem)lstKey.ElementAt(j);
p->KeyIndex = p->KeyIndex + 1;
}
for(int k=iObj+1;k<lstObj.GetSize();k++)
{
p = (pListItem)lstObj.ElementAt(k);
p->ObjIndex = p->ObjIndex + 1;
}
for(int i=Index+1;i<lstOrg.GetSize();i++)
{
p = (pListItem)lstOrg.ElementAt(i);
p->OrgIndex = p->OrgIndex + 1;
}
}

void CMyStringList::Add(CString &key,LPVOID obj)
{
CString s;
pListItem p = new ListItem();
CStringToPChar(key,&p->Key,p->Len);
p->obj = obj;
p->OrgIndex = lstOrg.GetSize();
lstOrg.Add((CObject *)p);

Insert_KeyLst(p,0,lstKey.GetSize()-1);
Insert_ObjLst(p,0,lstObj.GetSize()-1);

//调整各列表索引号
int iKey = p->KeyIndex;
int iObj = p->ObjIndex;
for(int j=iKey+1;j<lstKey.GetSize();j++)
{
p = (pListItem)lstKey.ElementAt(j);
p->KeyIndex = p->KeyIndex + 1;
}
for(int k=iObj+1;k<lstObj.GetSize();k++)
{
p = (pListItem)lstObj.ElementAt(k);
p->ObjIndex = p->ObjIndex + 1;
}
}

void CMyStringList::Add(LPVOID obj)
{
CString c = "";
Add(c,obj);
}

void CMyStringList::Add(CString &key)
{
Add(key,NULL);
}

int CMyStringList::GetObjIndex(LPVOID obj,int LowIndex,int HighIndex)
{
pListItem pComp;

if (LowIndex == HighIndex)
{
pComp = (pListItem)lstObj.ElementAt(LowIndex);
if (int(obj) == (int)pComp->obj)
return pComp->OrgIndex;
else
return -1;
}

//二分法比较
int iMiddle = (LowIndex + HighIndex)/2;
iMiddle = (iMiddle < 0)?0:iMiddle;
pComp = (pListItem)lstObj.ElementAt(iMiddle);
if (int(obj) == (int)pComp->obj) return pComp->OrgIndex;
if (int(obj) < (int)pComp->obj)
return GetObjIndex(obj,LowIndex,((iMiddle-1)<0?0:(iMiddle-1)));
else
return GetObjIndex(obj,iMiddle+1,HighIndex);
}

int CMyStringList::GetKeyIndex(char *p,int LowIndex,int HighIndex)
{
pListItem pComp;

if (LowIndex == HighIndex)
{
pComp = (pListItem)lstKey.ElementAt(LowIndex);
if (strcmp(p,pComp->Key) == 0)
return pComp->OrgIndex;
else
return -1;
}

//二分法比较
int iMiddle = (LowIndex + HighIndex)/2;
iMiddle = (iMiddle < 0)?0:iMiddle;
pComp = (pListItem)lstKey.ElementAt(iMiddle);
if (strcmp(p,pComp->Key) == 0) return pComp->OrgIndex;
if (strcmp(p,pComp->Key) < 0)
return GetKeyIndex(p,LowIndex,((iMiddle-1)<0?0:(iMiddle-1)));
else
return GetKeyIndex(p,iMiddle+1,HighIndex);
}

int CMyStringList::IndexOf(CString &key)
{
if (lstKey.GetSize()==0) return -1;

char *p;
int Len;
CStringToPChar(key,&p,Len);
int Index = GetKeyIndex(p,0,lstKey.GetSize()-1);
delete [Len]p;
return Index;
}

int CMyStringList::IndexOf(LPVOID obj)
{
if (lstObj.GetSize()==0) return -1;

return GetObjIndex(obj,0,lstKey.GetSize()-1);
}

void CMyStringList::Delete(CString &key)
{
int i = IndexOf(key);
if (i != -1) Delete(i);
}

void CMyStringList::Delete(LPVOID obj)
{
int i = IndexOf(obj);
if (i != -1) Delete(i);
}

void CMyStringList::Delete(int Index)
{
if ((Index < 0) || (Index > lstOrg.GetSize() - 1)) return;

int iKey;
int iObj;
pListItem p = (pListItem)lstOrg.ElementAt(Index);

//调整各列表索引号
iKey = p->KeyIndex;
iObj = p->ObjIndex;
for(int j=iKey+1;j<lstKey.GetSize();j++)
{
p = (pListItem)lstKey.ElementAt(j);
p->KeyIndex = p->KeyIndex - 1;
}
for(int k=iObj+1;k<lstObj.GetSize();k++)
{
p = (pListItem)lstObj.ElementAt(k);
p->ObjIndex = p->ObjIndex - 1;
}

for(int i=Index+1;i<lstOrg.GetSize();i++)
{
p = (pListItem)lstOrg.ElementAt(i);
p->OrgIndex = p->OrgIndex - 1;
}

//删除项目
p = (pListItem)lstOrg.ElementAt(Index);
lstOrg.RemoveAt(p->OrgIndex);
lstKey.RemoveAt(p->KeyIndex);
lstObj.RemoveAt(p->ObjIndex);
delete [p->Len]p->Key;
delete p;
}

int CMyStringList::GetSize()
{
return lstOrg.GetSize();
}

LPVOID CMyStringList::ElementAt_Obj(int Index)
{
ListItem *p;
p = (ListItem *)lstOrg.ElementAt(Index);
return p->obj;
}

LPVOID CMyStringList::ElementAt_Key(int Index)
{
ListItem *p;
p = (ListItem *)lstOrg.ElementAt(Index);
return p->Key;
}

void CMyStringList::RemoveAll()
{
ListItem *p;
for(int i=0;i<lstOrg.GetSize();i++)
{
p = (ListItem *)lstOrg.ElementAt(i);
delete [p->Len]p->Key;
delete p;
}
lstOrg.RemoveAll();
lstObj.RemoveAll();
lstKey.RemoveAll();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: