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

// 头文件: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();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值