您的位置:首页 > 其它

字符串逻辑比较函数---StrCmpLogicalW的模拟实现

2008-07-06 16:48 591 查看
我们最熟悉的字符串比较函数莫过于strcmp了,但这个函数仅仅是根据字符进行比较,没有考虑字符串的逻辑意义,为此微软为我们提供了一个StrCmpLogicalW函数,它比较数字时不将其视为文本而是视为数值。
我们可以从下列这个简单的字符串数组排序的结果看出这两个函数的区别:
使用StrCmpLogicalW进行比较的结果:


2string


3string


20string


st2ring


st3ring


st20ring


string2


string3


string20



使用简单的strcmp函数进行比较的结果:


20string


2string


3string


st20ring


st2ring


st3ring


string2


string20


string3



下面这段代码就是模仿这个函数的实现:


#include <iostream>


#include <afx.h>


#include "deelx.h"


using namespace std;




#define MATCH_NUMBERS "[+-]?//d+(//.//d+)?"






int Compare(CString csText1, CString csText2)






{


static CRegexp reg(MATCH_NUMBERS);


int nEnd1 = 0, nEnd2 = 0;





while(1)






{


MatchResult ret1 = reg.Match(csText1, nEnd1);


MatchResult ret2 = reg.Match(csText2, nEnd2);





CString const& csSubText1 = ret1.IsMatched() ? csText1.Mid(nEnd1, ret1.GetStart() - nEnd1) : csText1;


CString const& csSubText2 = ret2.IsMatched() ? csText2.Mid(nEnd2, ret2.GetStart() - nEnd2) : csText2;





//子串不同,则返回


if (csSubText1 != csSubText2)


return csSubText1 > csSubText2 ? 1 : -1;







/**//*


既然两个字符串相等, 而两个字符串又已经消耗完, 那自然可以返回了.


*/


if (! ret1.IsMatched() && ! ret2.IsMatched()) return 0;





if (ret1.IsMatched() && ret2.IsMatched())






{//字符串还未消耗完毕,继续按逻辑比较




/**//*


GetGroupStart() 返回正则表达式中"(//.//d+)" 这一个组的起始位置. 如果没有匹配, 则返回-1; (可查看deelx 的说明文档)


这个组是否匹配意味着捕获的数字是否带有小数点以及小数部分.


如果捕获的两个数字有一个带有小数部分. 则按浮点数处理. 否则按整数处理


*/


if (ret1.GetGroupStart(1) >= 0 || ret2.GetGroupStart(1) >= 0)






{//带小数点,按浮点数比较数值大小


double dNum1 = _tcstod(csText1.Mid(ret1.GetStart(), ret1.GetEnd() - ret1.GetStart()), 0);


double dNum2 = _tcstod(csText2.Mid(ret2.GetStart(), ret2.GetEnd() - ret2.GetStart()), 0);


if (dNum1 != dNum2) return dNum1 > dNum2 ? 1 : -1;


}


else






{//按整数处理,比较两个数的数值大小


__int64 nNum1 = _ttoi64(csText1.Mid(ret1.GetStart(), ret1.GetEnd() - ret1.GetStart()));


__int64 nNum2 = _ttoi64(csText2.Mid(ret2.GetStart(), ret2.GetEnd() - ret2.GetStart()));


if (nNum1 != nNum2) return nNum1 > nNum2 ? 1 : -1;


}





nEnd1 = ret1.GetEnd();


nEnd2 = ret2.GetEnd();


}


else






{//现在两个里面肯定有且只有一个IsMatch() 不为真


return ret1.IsMatched() ? 1 : -1;


}


}


return 0;


}




int main()






{


CString str1("st3ring"),str2 ("st20ring");


int result;


result = Compare(str1,str2);


std::cout<<"result is: "<<result<<endl;


result = strcmp(str1.GetBuffer(10),str2.GetBuffer(10));


cout<<"result is: "<<result<<endl;


system("pause");


return 0;


}



代码中使用了一个开源的正则表达式引擎,DEELX 正则表达式引擎
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: