2653885 发表于 2015-11-23 15:50:55

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

2亿个浮点数中求最大的100万之和
题目:有一个文件中保存了2亿个浮点数,每个浮点数都以'/n'分隔。求最大的100万个浮点数之和。
算法:1. 首先建立一个容量为100万(nTop)的float数组,从文件读取浮点数填充。2. 利用堆排序对该100万条记录排序(确保第一个元素为最小值)3. 从文件中读取一个浮点数与第一个元素比较,如果大于第一个元素则替换该元素,并调整堆的结构。4. 重复步骤3一直到数据读取完5. 将数组中的元素全部相加,得到结果
源代码:
[*]//CTopSum.h
[*]#pragma once
[*]#include <windows.h>
[*]
[*]class CTopSum
[*]{
[*]public:
[*]    CTopSum();
[*]    ~CTopSum(void);
[*]
[*]public:
[*]    static void HeapAdjust(float* pnData, int nStart, int nLen);
[*]    static void HeapSort(float* pnData, int nLen);
[*]
[*]public:
[*]    float GetTopSum(LPCTSTR lpszFile, int& nTop);
[*]
[*]private:
[*]    void Clear();
[*]    static void HeapAdjustLit(float* pnData, int nStart, int nLen);
[*]private:
[*]    float*  m_pfData;
[*]};
[*]
[*]//CTopSum.cpp
[*]#include "StdAfx.h"
[*]#include "topsum.h"
[*]#include <iostream>
[*]
[*]using namespace std;
[*]
[*]CTopSum::CTopSum()
[*]{
[*]    m_pfData = NULL;
[*]}
[*]
[*]CTopSum::~CTopSum(void)
[*]{
[*]    Clear();
[*]}
[*]
[*]void CTopSum::Clear()
[*]{
[*]    if (NULL != m_pfData)
[*]    {
[*]        delete[] m_pfData;
[*]        m_pfData = NULL;
[*]    }
[*]}
[*]
[*]//获取前top位的总和
[*]float CTopSum::GetTopSum(LPCTSTR lpszFile, int& nTop)
[*]{
[*]    FILE*   fp      = NULL;
[*]    float   fData   = 0.0f;
[*]    float   fSum    = 0.0f;
[*]    int     i       = 0;
[*]
[*]    //判断输入参数
[*]    if ( (NULL == lpszFile) || (nTop <= 0) )
[*]    {
[*]        cout << "error parameter" << endl;
[*]        return 0.0f;
[*]    }
[*]    
[*]    //清除操作
[*]    Clear();
[*]
[*]    //打开文件
[*]    fp = ::fopen(lpszFile, "r");
[*]
[*]    if (NULL == fp)
[*]    {
[*]        cout << "open file failed!" << endl;
[*]        return 0.0f;
[*]    }
[*]
[*]    //分配空间
[*]    m_pfData = new float;
[*]
[*]    if (NULL == m_pfData)
[*]    {
[*]        cout << "new operator failed!" << endl;
[*]        return 0.0f;
[*]    }
[*]
[*]    cout << "please wait..." << endl;
[*]
[*]    //读取前nTop个数据
[*]    for (i = 0; i < nTop; i++)
[*]    {
[*]        if (EOF != ::fscanf(fp, "%f/n", &fData))
[*]        {
[*]            m_pfData = fData;
[*]        }
[*]        else
[*]        {
[*]            break;
[*]        }
[*]    }
[*]
[*]    //最大的个数小于nTop,求前i个数据
[*]    if (i < nTop)
[*]    {
[*]        nTop = i;       
[*]    }
[*]    else
[*]    {       
[*]        CTopSum::HeapSort(m_pfData, nTop);//排序
[*]
[*]        while (EOF != ::fscanf(fp, "%f/n", &fData))
[*]        {
[*]            if (fData > m_pfData)
[*]            {
[*]                //交换并调整堆
[*]                m_pfData = fData;
[*]                CTopSum::HeapAdjustLit(m_pfData, 0, nTop);
[*]            }
[*]        }
[*]    }
[*]
[*]    fSum = 0;
[*]    for (i = 0; i < nTop; i++)
[*]    {
[*]        fSum += m_pfData;
[*]    }
[*]
[*]    return fSum;
[*]}
[*]
[*]//调整大根堆
[*]void CTopSum::HeapAdjust(float* pnData, int nStart, int nLen)
[*]{
[*]    int nMaxChild = 0;
[*]    float fTemp = 0;
[*]
[*]    while ( ( 2 * nStart + 1) < nLen)
[*]    {
[*]        nMaxChild = 2 * nStart + 1;
[*]        if ( (2 * nStart + 2) < nLen)
[*]        {
[*]            //比较左子树和右子树,记录最大值的Index
[*]            if (pnData < pnData)
[*]            {
[*]                nMaxChild = 2 * nStart + 2;
[*]            }
[*]        }
[*]
[*]        //change data
[*]        if (pnData < pnData)
[*]        {
[*]            //交换nStart与nMaxChild的数据
[*]            fTemp = pnData;
[*]            pnData = pnData;
[*]            pnData = fTemp;
[*]
[*]            //堆被破坏,需要重新调整
[*]            nStart = nMaxChild;
[*]        }
[*]        else
[*]        {
[*]            //比较左右孩子均大则堆未破坏,不再需要调整
[*]            break;
[*]        }
[*]    }
[*]}
[*]
[*]//堆排序
[*]void CTopSum::HeapSort(float* pnData, int nLen)
[*]{
[*]    int i = 0;
[*]    float nTemp = 0;
[*]
[*]    //将pnData建成大根堆
[*]    for (i = nLen / 2  - 1; i >= 0; i--)
[*]    {
[*]        CTopSum::HeapAdjust(pnData, i, nLen);
[*]    }
[*]
[*]    for (i = nLen - 1; i > 0; i--)
[*]    {
[*]        nTemp = pnData;
[*]        pnData = pnData;
[*]        pnData = nTemp;
[*]
[*]        //将pnData重写建成大根堆
[*]        CTopSum::HeapAdjust(pnData, 0, i);
[*]    }
[*]}
[*]
[*]void CTopSum::HeapAdjustLit(float* pnData, int nStart, int nLen)
[*]{
[*]    int nMinChild = 0;
[*]    float fTemp = 0;
[*]
[*]    while ( ( 2 * nStart + 1) < nLen)
[*]    {
[*]        nMinChild = 2 * nStart + 1;
[*]        if ( (2 * nStart + 2) < nLen)
[*]        {
[*]            //比较左子树和右子树,记录最大值的Index
[*]            if (pnData < pnData)
[*]            {
[*]                nMinChild = 2 * nStart + 2;
[*]            }
[*]        }
[*]
[*]        //change data
[*]        if (pnData > pnData)
[*]        {
[*]            //交换nStart与nMaxChild的数据
[*]            fTemp = pnData;
[*]            pnData = pnData;
[*]            pnData = fTemp;
[*]
[*]            //堆被破坏,需要重新调整
[*]            nStart = nMinChild;
[*]        }
[*]        else
[*]        {
[*]            //比较左右孩子均大则堆未破坏,不再需要调整
[*]            break;
[*]        }
[*]    }
[*]}
[*]
[*]//main.cpp
[*]#include "stdafx.h"
[*]#include "topsum.h"
[*]#include <iostream>
[*]
[*]using namespace std;
[*]
[*]int _tmain(int argc, _TCHAR* argv[])
[*]{
[*]    TCHAR   szFile = {0};
[*]    int     nNum = 0;
[*]    CTopSum objTopSum;
[*]
[*]    cout << "please input count file name:" << endl;
[*]    cin >> szFile;
[*]
[*]    cout << "please input top num:"<< endl;
[*]    cin >> nNum;
[*]
[*]    cout << "top " << nNum << " value = " << objTopSum.GetTopSum(szFile, nNum) << endl;
[*]
[*]    ::system("pause");
[*]
[*]    return 0;
[*]}
[*]
[*]
[*]
页: [1]
查看完整版本: 2亿个浮点数中求最大的100万之和