标签:
#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 << "\ntop " << nNum << " value = " << fSum << endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/dynas/p/4936558.html