2亿个浮点数中求最大的100万之和

2亿个浮点数中求最大的100万之和

题目:有一个文件中保存了2亿个浮点数,每个浮点数都以'/n'分隔。求最大的100万个浮点数之和。

算法:
1. 首先建立一个容量为100万(nTop)的float数组,从文件读取浮点数填充。
2. 利用堆排序对该100万条记录排序(确保第一个元素为最小值)
3. 从文件中读取一个浮点数与第一个元素比较,如果大于第一个元素则替换该元素,并调整堆的结构。
4. 重复步骤3一直到数据读取完
5. 将数组中的元素全部相加,得到结果

源代码:
  1. //CTopSum.h
  2. #pragma once
  3. #include <windows.h>
  4. class CTopSum
  5. {
  6. public:
  7.     CTopSum();
  8.     ~CTopSum(void);
  9. public:
  10.     static void HeapAdjust(float* pnData, int nStart, int nLen);
  11.     static void HeapSort(float* pnData, int nLen);
  12. public:
  13.     float GetTopSum(LPCTSTR lpszFile, int& nTop);
  14. private:
  15.     void Clear();
  16.     static void HeapAdjustLit(float* pnData, int nStart, int nLen);
  17. private:
  18.     float*  m_pfData;
  19. };
  20. //CTopSum.cpp
  21. #include "StdAfx.h"
  22. #include "topsum.h"
  23. #include <iostream>
  24. using namespace std;
  25. CTopSum::CTopSum()
  26. {
  27.     m_pfData = NULL;
  28. }
  29. CTopSum::~CTopSum(void)
  30. {
  31.     Clear();
  32. }
  33. void CTopSum::Clear()
  34. {
  35.     if (NULL != m_pfData)
  36.     {
  37.         delete[] m_pfData;
  38.         m_pfData = NULL;
  39.     }
  40. }
  41. //获取前top位的总和
  42. float CTopSum::GetTopSum(LPCTSTR lpszFile, int& nTop)
  43. {
  44.     FILE*   fp      = NULL;
  45.     float   fData   = 0.0f;
  46.     float   fSum    = 0.0f;
  47.     int     i       = 0;
  48.     //判断输入参数
  49.     if ( (NULL == lpszFile) || (nTop <= 0) )
  50.     {
  51.         cout << "error parameter" << endl;
  52.         return 0.0f;
  53.     }
  54.     
  55.     //清除操作
  56.     Clear();
  57.     //打开文件
  58.     fp = ::fopen(lpszFile, "r");
  59.     if (NULL == fp)
  60.     {
  61.         cout << "open file failed!" << endl;
  62.         return 0.0f;
  63.     }
  64.     //分配空间
  65.     m_pfData = new float[nTop];
  66.     if (NULL == m_pfData)
  67.     {
  68.         cout << "new operator failed!" << endl;
  69.         return 0.0f;
  70.     }
  71.     cout << "please wait..." << endl;
  72.     //读取前nTop个数据
  73.     for (i = 0; i < nTop; i++)
  74.     {
  75.         if (EOF != ::fscanf(fp, "%f/n", &fData))
  76.         {
  77.             m_pfData[i] = fData;
  78.         }
  79.         else
  80.         {
  81.             break;
  82.         }
  83.     }
  84.     //最大的个数小于nTop,求前i个数据
  85.     if (i < nTop)
  86.     {
  87.         nTop = i;       
  88.     }
  89.     else
  90.     {       
  91.         CTopSum::HeapSort(m_pfData, nTop);//排序
  92.         while (EOF != ::fscanf(fp, "%f/n", &fData))
  93.         {
  94.             if (fData > m_pfData[0])
  95.             {
  96.                 //交换并调整堆
  97.                 m_pfData[0] = fData;
  98.                 CTopSum::HeapAdjustLit(m_pfData, 0, nTop);
  99.             }
  100.         }
  101.     }
  102.     fSum = 0;
  103.     for (i = 0; i < nTop; i++)
  104.     {
  105.         fSum += m_pfData[i];
  106.     }
  107.     return fSum;
  108. }
  109. //调整大根堆
  110. void CTopSum::HeapAdjust(float* pnData, int nStart, int nLen)
  111. {
  112.     int nMaxChild = 0;
  113.     float fTemp = 0;
  114.     while ( ( 2 * nStart + 1) < nLen)
  115.     {
  116.         nMaxChild = 2 * nStart + 1;
  117.         if ( (2 * nStart + 2) < nLen)
  118.         {
  119.             //比较左子树和右子树,记录最大值的Index
  120.             if (pnData[2 * nStart + 1] < pnData[2 * nStart + 2])
  121.             {
  122.                 nMaxChild = 2 * nStart + 2;
  123.             }
  124.         }
  125.         //change data
  126.         if (pnData[nStart] < pnData[nMaxChild])
  127.         {
  128.             //交换nStart与nMaxChild的数据
  129.             fTemp = pnData[nStart];
  130.             pnData[nStart] = pnData[nMaxChild];
  131.             pnData[nMaxChild] = fTemp;
  132.             //堆被破坏,需要重新调整
  133.             nStart = nMaxChild;
  134.         }
  135.         else
  136.         {
  137.             //比较左右孩子均大则堆未破坏,不再需要调整
  138.             break;
  139.         }
  140.     }
  141. }
  142. //堆排序
  143. void CTopSum::HeapSort(float* pnData, int nLen)
  144. {
  145.     int i = 0;
  146.     float nTemp = 0;
  147.     //将pnData[0, Len-1]建成大根堆
  148.     for (i = nLen / 2  - 1; i >= 0; i--)
  149.     {
  150.         CTopSum::HeapAdjust(pnData, i, nLen);
  151.     }
  152.     for (i = nLen - 1; i > 0; i--)
  153.     {
  154.         nTemp = pnData[0];
  155.         pnData[0] = pnData[i];
  156.         pnData[i] = nTemp;
  157.         //将pnData[0...i]重写建成大根堆
  158.         CTopSum::HeapAdjust(pnData, 0, i);
  159.     }
  160. }
  161. void CTopSum::HeapAdjustLit(float* pnData, int nStart, int nLen)
  162. {
  163.     int nMinChild = 0;
  164.     float fTemp = 0;
  165.     while ( ( 2 * nStart + 1) < nLen)
  166.     {
  167.         nMinChild = 2 * nStart + 1;
  168.         if ( (2 * nStart + 2) < nLen)
  169.         {
  170.             //比较左子树和右子树,记录最大值的Index
  171.             if (pnData[2 * nStart + 2] < pnData[2 * nStart + 1])
  172.             {
  173.                 nMinChild = 2 * nStart + 2;
  174.             }
  175.         }
  176.         //change data
  177.         if (pnData[nStart] > pnData[nMinChild])
  178.         {
  179.             //交换nStart与nMaxChild的数据
  180.             fTemp = pnData[nStart];
  181.             pnData[nStart] = pnData[nMinChild];
  182.             pnData[nMinChild] = fTemp;
  183.             //堆被破坏,需要重新调整
  184.             nStart = nMinChild;
  185.         }
  186.         else
  187.         {
  188.             //比较左右孩子均大则堆未破坏,不再需要调整
  189.             break;
  190.         }
  191.     }
  192. }
  193. //main.cpp
  194. #include "stdafx.h"
  195. #include "topsum.h"
  196. #include <iostream>
  197. using namespace std;
  198. int _tmain(int argc, _TCHAR* argv[])
  199. {
  200.     TCHAR   szFile[MAX_PATH] = {0};
  201.     int     nNum = 0;
  202.     CTopSum objTopSum;
  203.     cout << "please input count file name:" << endl;
  204.     cin >> szFile;
  205.     cout << "please input top num:"<< endl;
  206.     cin >> nNum;
  207.     cout << "top " << nNum << " value = " << objTopSum.GetTopSum(szFile, nNum) << endl;
  208.     ::system("pause");
  209.     return 0;
  210. }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值