CStringArray 排序号

CStringArray是MSVC 的一个容器类,
我们为它写一个排序函数.
函数声明:
voidSort(CStringArray&ca,//排序对象
BOOLascending,//TRUE=升序,FALSE=降序;
BOOLcaseSensitive);//TRUE=区别大小写,FALSE=忽略大小写我们
分别用C和C 的方法实现Sort,先看C的方法.




=================C的实现=====================================
我们使用C标准库的qsort函数.qsort的声明是这样的:
voidqsort(void*base,
size_tnum,
size_twidth,
int(__cdecl*compare)(constvoid*elem1,constvoid*elem2));
其中参数:
base=ca.GetData();
num=ca.GetSize();
width=sizeof(CString);
第四个参数是"比较"函数的指针,这个"比较"函数须由我们提供,但问题在于"比较"函
数只能接受两个参数,我们无法把ascending和caseSensitive传递给它,也就是说
我们需要4个"比较"函数.下面是这4个"比较"函数的声明:
intcompare00(constvoid*elem1,constvoid*elem2);
intcompare01(constvoid*elem1,constvoid*elem2);
intcompare10(constvoid*elem1,constvoid*elem2);
intcompare11(constvoid*elem1,constvoid*elem2);
compare后面的数字对应于ascending和caseSensitive的值,例如compare10表示
ascending=TRUE,caseSensitive=FALSE.我们再来看Sort的实现:

voidSort(CStringArray&ca,
BOOLascending,
BOOLcaseSensitive)
{
intf=0;
if(ascending)
f=2;
if(caseSensitive)
f|=1;
switch(f)
{
case0x00:
qsort(ca.GetData(),ca.GetSize(),sizeof(CString),compare00);
break;
case0x01:
qsort(ca.GetData(),ca.GetSize(),sizeof(CString),compare01);
break;
case0x10:
qsort(ca.GetData(),ca.GetSize(),sizeof(CString),compare10);
break;
case0x11:
qsort(ca.GetData(),ca.GetSize(),sizeof(CString),compare11);
break;
}
}
4个"比较"函数也很容易实现,例如:
intcompare00(constvoid*elem1,constvoid*elem2)
{
return(((CString*)elem1)->CompareNoCase(*((CString*)elem2))*-1);
}
=================C 的实现=====================================
我们使用C 的STL的sort
函数模板:
templatevoidsort(RanItfirst,RanItlast,Predpr);
其中参数:
first=ca.GetData();
last=ca.GetData() ca.GetSize();
第三个参数是一个"FunctionObject",我们不想象C方法那样用4个"比较"函数,
而是设计一个"比较"类:
classCStringCompare
{
public:
CStringCompare(BOOLascending,BOOLcaseSensitive)
{
if(caseSensitive)
m_pCompfunc=CString::Compare;
else
m_pCompfunc=CString::CompareNoCase;
m_ASC=ascending;
}
BOOLoperator()(constCString&cs1,constCString&cs2)const
{
return(m_ASC?(cs1.*m_pCompfunc)(cs2)<0:((cs1.*m_pCompfunc)(cs2)>=0));
}
protected:
typedefint(CString::*CompareMemberFunc)(constTCHAR*)const;
CompareMemberFunc m_pCompfunc;
BOOL m_ASC;
};
Sort的C 实现:
voidSort(CStringArray&ca,BOOLascending,BOOLcaseSensitive)
{
CStringComparecp(ascending,caseSensitive);

sort(ca.GetData(),ca.GetData() ca.GetSize(),cp);
}
=================C 的实现的改进=====================================进行
速度测试,会发现C 的实现要比C的实现慢的多,
这是因为在C 的过程中需要生成很多临时CString.
下面我们来改进:
classCStringCompare
{
public:
typedefstruct
{
chardata[sizeof(CString)];
}CSTRING;
CStringCompare(CStringArray&ca,BOOLascending,BOOLcaseSensitive):m_CA(ca)
{
if(caseSensitive)
m_pCompfunc=CString::Compare;
else
m_pCompfunc=CString::CompareNoCase;
m_ASC=ascending;
}
BOOLoperator()(constCSTRING&cs1,constCSTRING&cs2)const
{
constCString*pcs1=reintERPret_cast(&cs1);
constCString*pcs2=reinterpret_cast(&cs2);
return(m_ASC?(pcs1->*m_pCompfunc)(*pcs2)<0
:((pcs1->*m_pCompfunc)(*pcs2)>=0));
}
CSTRING*begin()
{
return(reinterpret_cast(m_CA.GetData()));
}
CSTRING*end()
{
return(reinterpret_cast(m_CA.GetData() m_CA.GetSize()));
}
protected:
typedefint(CString::*CompareMemberFunc)(constTCHAR*)const;

CompareMemberFunc m_pCompfunc;
BOOLm_ASC;
CStringArray& m_CA;
};
voidSort(CStringArray&ca,BOOLascending,BOOLcaseSensitive)
{
CStringComparecp(ca,ascending,caseSensitive);
sort(cp.begin(),cp.end(),cp);
}
现在速度差不多了,不过用reinterpret_cast是否安全呢?分析看吧.在众多的C 编译
器中,MSVC属于较好的实现,但应该看到一直到最新的VC7,都把标准C (ISO98)放到一
个灰暗的位置上,许多特性都没有实现.有人说会用VC不等于懂C 大概是因此而来吧.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值