• 最大k个数,以及类模板


    #include <iostream>
    using namespace std;
    
    template<class T>
    class CTopK
    {
    public:
        CTopK();
        ~CTopK();
        T*  m_Data;
        int GetTopK(const char* sFile, int& nTop);
    private:
        void Clear();
        void HeapAdjust(int nStart, int nLen);
        void BuildHeap(int nLen);
    };
    
    template<class T>
    CTopK<T>::CTopK()
    {
        m_Data = NULL;
    }
    
    template<class T>
    CTopK<T>::~CTopK()
    {
        Clear();
    }
    
    template<class T>
    void CTopK<T>::Clear()
    {
        if (NULL != m_Data)
        {
            delete[] m_Data;
            m_Data = NULL;
        }
    }
    
    //获取前top的k个数
    template<class T>
    int CTopK<T>::GetTopK(const char* sFile, int& nTop)
    {
        FILE* fp = NULL;
        T fData;
        int i = 0;
    
        //判断输入参数
        if ( (NULL == sFile) || (nTop <= 0) )
        {
            cout << "error parameter" << endl;
            return -1;
        }
    
        //清除操作
        Clear();
    
        //打开文件
        fp = fopen(sFile, "r");
        if (NULL == fp)
        {
            cout << "open file failed!" << endl;
            return -1;
        }
    
        //分配空间
        m_Data = new T[nTop];
        if (NULL == m_Data)
        {
            cout << "new operator failed!" << endl;
            return -1;
        }
    
        cout << "please wait..." << endl;
    
        //读取前nTop个数据,注意数据的类型T
        for (i = 0; i < nTop; i++)
        {
            if (EOF != fscanf(fp, "%d", &fData))
            {
                m_Data[i] = fData;
            }
            else
            {
                break;
            }
        }
    
        //最大的个数小于nTop,求前i个数据
        if (i < nTop)
        {
            nTop = i;
        }
        else
        {
            BuildHeap(nTop);//建立小顶堆
    
            while (EOF != fscanf(fp, "%d", &fData))
            {
                if (fData > m_Data[0])
                {
                    //交换并调整堆
                    m_Data[0] = fData;
                    HeapAdjust(0, nTop);
                }
            }
        }
    
        return 0;
    }
    
    //调整小根堆,堆顶为Top K最小
    template<class T>
    void CTopK<T>::HeapAdjust(int nStart, int nLen)
    {
        int nMinChild = 0;
        T fTemp;
    
        while ( ( 2 * nStart + 1) < nLen)
        {
            nMinChild = 2 * nStart + 1;
            if ( (2 * nStart + 2) < nLen)
            {
                //比较左子树和右子树,记录最小值的Index
                if (m_Data[2 * nStart + 2] < m_Data[2 * nStart + 1])
                {
                    nMinChild = 2 * nStart + 2;
                }
            }
    
            //change data
            if (m_Data[nStart] > m_Data[nMinChild])
            {
                //交换nStart与nMaxChild的数据
                fTemp = m_Data[nStart];
                m_Data[nStart] = m_Data[nMinChild];
                m_Data[nMinChild] = fTemp;
    
                //堆被破坏,需要重新调整
                nStart = nMinChild;
            }
            else
            {
                //比较左右孩子均大则堆未破坏,不再需要调整
                break;
            }
        }
    }
    
    //建立堆
    template<class T>
    void CTopK<T>::BuildHeap(int nLen)
    {
        int i = 0;
        T nTemp;
    
        //将m_Data[0, Len-1]建成小根堆,这里只维护一个小根堆,不排序
        for (i = nLen / 2  - 1; i >= 0; i--)
        {
            HeapAdjust(i, nLen);
        }
    }
    
    int main(int argc, char* argv[])
    {
        char   szFile[100] = {0};
        int     nNum = 0;
        CTopK<int> objTopSum;
    
        cout << "please input count file name:" << endl;
        cin >> szFile;
        cout << "please input top num:"<< endl;
        cin >> nNum;
        objTopSum.GetTopK(szFile, nNum);
    
        int fSum = 0;
        for (int i = 0; i < nNum; i++)
        {
            cout<<objTopSum.m_Data[i]<<" ";
            fSum += objTopSum.m_Data[i];
        }
        cout << "
    top " << nNum << " value = " << fSum << endl;
    
        return 0;
    }
  • 相关阅读:
    eclipse下jsp文件报错解决方法
    使用vscode搭建本地的websocket
    tomcat的首次登录配置
    tomcat配置报错解决方法 The jre_home environment variable is not defined correctly
    cento升级openssl依旧显示老版本
    Centos6安装mysql5.7最新版
    Neutron服务组件
    网络OSI 7层模型
    Kubernetes的核心技术概念和API对象
    Xen 虚拟化技术
  • 原文地址:https://www.cnblogs.com/dynas/p/4936558.html
Copyright © 2020-2023  润新知