首页 IP地址查询 | Alexa排名查询 | 手机归属地查询
设为首页 收藏本站
  • 网络编程网络编程
  • 软件编程软件编程
  • 数据库技术数据库技术
  • 编程学院
  • 业界资讯 业界资讯
  • 源码中心源码中心
  • 会员中心会员中心
  • 页面导航: 首页MFC编程变量 → CStringArray排序

    CStringArray排序

    发布:华夏名网 发布日期:2009-09-16 字体:[增加 减小] 类型:转载

    StringArray是MS VC++的一个容器类,
    我们为他写一个排序函数.
    函数声明:
    void Sort(CStringArray &ca,     //排序对象
              BOOL ascending,       //TRUE=升序, FALSE=降序; 
              BOOL caseSensitive);   //TRUE=差别大小写, FALSE=忽略大小写我们
    分别用C和C++的方法实现Sort, 先看C的方法.
     

     

    ================= C 的实现 =====================================
    我们使用C标准库的qsort函数. qsort的声明是这样的:
    void qsort(void *base,
                size_t num,
                size_t width,
                int(__cdecl *compare)(const void *elem1, const void *elem2 ));
    其中参数:
        base = ca.GetData();
        num  = ca.GetSize();
        width= sizeof(CString);
    第四个参数是"比较"函数的指针, 这个"比较"函数须由我们提供, 但问题在于"比较"函
    数只能接受两个参数, 我们无法把ascending和caseSensitive传递给他, 也就是说
    我们需要4个"比较"函数. 下面是这4个"比较"函数的声明:
        int compare00(const void *elem1, const void *elem2);
        int compare01(const void *elem1, const void *elem2);
        int compare10(const void *elem1, const void *elem2);
        int compare11(const void *elem1, const void *elem2);
    compare后面的数字对应于ascending和caseSensitive的值,例如compare10表示
    ascending=TRUE, caseSensitive=FALSE.我们再来看Sort的实现:
     
    void Sort(CStringArray &ca,
                BOOL ascending,
                BOOL caseSensitive)
    {
        int f=0;
        if(ascending) 
            f=2;
        if(caseSensitive) 
            f|=1;
        switch(f) 
        { 
        case 0x00:  
            qsort(ca.GetData(), ca.GetSize(), sizeof(CString), compare00);  
        break; 
        case 0x01:  
            qsort(ca.GetData(), ca.GetSize(), sizeof(CString), compare01);  
        break; 
        case 0x10:  
            qsort(ca.GetData(), ca.GetSize(), sizeof(CString), compare10);  
        break; 
        case 0x11:  
            qsort(ca.GetData(), ca.GetSize(), sizeof(CString), compare11);  
        break; 
        } 
    }
    4个"比较"函数也非常容易实现, 例如:
    int compare00(const void *elem1, const void *elem2)
    {
        return(((CString*)elem1)->CompareNoCase(*((CString*)elem2))*-1);
    }
    ================= C++ 的实现 =====================================
    我们使用C++的STL的sort
    函数模板:
        templatevoid sort(RanIt first, RanIt last, Pred pr);
    其中参数:
        first=ca.GetData();
        last =ca.GetData()+ca.GetSize();
    第三个参数是个"Function Object", 我们不想象C方法那样用4个"比较"函数,
    而是设计一个"比较"类:
    class CStringCompare 
    {
    public: 
        CStringCompare(BOOL ascending, BOOL caseSensitive)  
    {  
        if(caseSensitive)   
        m_pCompfunc=CString::Compare;  
        else   
        m_pCompfunc=CString::CompareNoCase;  
        m_ASC=ascending;  

    BOOL operator()(const CString & cs1, const CString&cs2) const  
    {  
        return(m_ASC? (cs1.*m_pCompfunc)(cs2)<0 : ((cs1.*m_pCompfunc)(cs2)>=0));  
    }
    protected:
        typedef int (CString::*CompareMemberFunc)(const TCHAR*) const; 
        CompareMemberFunc     m_pCompfunc; 
        BOOL            m_ASC; 
    };
    Sort的C++实现:
    void Sort(CStringArray &ca, BOOL ascending, BOOL caseSensitive) 
    {
        CStringCompare cp(ascending, caseSensitive);
        sort(ca.GetData(), ca.GetData()+ca.GetSize(), cp); 
    }
    ================= C++ 的实现的改进 =====================================进行
    速度测试, 会发现C++的实现要比C的实现慢的多,
    这是因为在C++的过程中需要生成非常多临时CString.
    下面我们来改进:
    class CStringCompare 
    {
    public: 
        typedef struct
        {
            char data[sizeof(CString)];
        } CSTRING; 
        CStringCompare(CStringArray & ca, BOOL ascending, BOOL caseSensitive):m_CA(ca)  
        {  
            if(caseSensitive)   
                m_pCompfunc=CString::Compare;  
            else   
                m_pCompfunc=CString::CompareNoCase;  
            m_ASC=ascending;  
        } 
    BOOL operator()(const CSTRING & cs1, const CSTRING&cs2) const  
    {  
        const CString * pcs1=reinterpret_cast(&cs1);  
        const CString * 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:
        typedef int (CString::*CompareMemberFunc)(const TCHAR*) const;
     
        CompareMemberFunc     m_pCompfunc; 
        BOOL     m_ASC; 
        CStringArray &       m_CA; 
    };
    void Sort(CStringArray &ca, BOOL ascending, BOOL caseSensitive) 
    {
        CStringCompare cp(ca, ascending, caseSensitive);
        sort(cp.begin(), cp.end(),  cp); 
    }
    目前速度差不多了, 不过用reinterpret_cast是否安全呢? 分析看吧.在众多的C++编译
    器中, MS VC属于较好的实现, 但应该看到一直到最新的VC7, 都把标准C++(ISO98)放到一
    个灰暗的位置上, 许多特性都没有实现. 有人说会用VC不等于懂C++大概是因此而来吧.


    #

     

    以上内容由 华夏名网 搜集整理,如转载请注明原文出处,并保留这一部分内容。
      “华夏名网” http://www.sudu.cn 和 http://www.bigwww.com 是成都飞数科技有限公司的网络服务品牌,专业经营虚拟主机,域名注册,VPS,服务器租用业务。公司创建于2002年,经过6年的高速发展,“华夏名网” 已经成为我国一家知名的互联网服务提供商,被国外权威机构webhosting.info评价为25大IDC服务商之一。


    Tags: CStringArray
    为配合网络严查,文章评论将关闭敬请谅解.
    同 类 文 章
    最 近 更 新
    热 点 排 行