如果在 HDD = {1,1,5,7,8,1,6,10,20,1}上分配了一个非常大的数组,我们需要找出有多少不同价值存在。所提到的阵列的解决方案是总共7个,7个不同的数字{1,5,6,7,6,10,20}。没有必要保存数字。
给出了一些提示,我需要在HDD和RAM上工作。但是,HDD明显大于RAM。因此,当所有值都不同时,不能保留哈希表和链表。根据我的理解,我需要分配K个固定大小的数组(每个m个元素)。之后,我需要填充所有k个数组,将每个数组排序。然后比较它们并计算不同的部分并再次填充它们直到完成HDD上分配的所有值。我的问题是最后一部分,一旦数组排序后我需要做什么?
编辑:rutime示例,HDD可能包含10 ^ 10条记录,RAM可能只包含10 ^ 5, 并且K = 10,M = 10.对于每个处理的数组,需要读取该特定数组的下一个M值。
应该只有一个计数器,说明不同值的数量。最大的数字可能是N
感谢
答案 0 :(得分:0)
这是我的解决方案。我定义了2个向量,第一个向量表示Hdd数据,另一个向量表示Hdd向量内的偏移。
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <iterator>
#include <direct.h>
#define FILE_NAME "\\data.txt"
#define ROWS 10
#define MAX_LINE 100
#define ARRSIZE(arr) sizeof(arr) / sizeof(arr[0])
class CPair
{
public:
CPair(__int64 nOffset) : m_llOffset(nOffset), m_llCurOffset(nOffset), m_bChecked(0)
{ }
__int64 m_llOffset;
__int64 m_llCurOffset;
bool m_bChecked;
};
std::vector<long> vecHDD;
std::vector<CPair> vecOffsets;
long RetrieveValueFromHDD(__int64& i64Offset)
{
return vecHDD[(long)i64Offset];
}
void FindDistinct()
{
// calculate how many fragments within the HDD we've got
long nFragments = (vecHDD.size() / ROWS);
long nCount = 0;
while(nFragments > 0)
{
long nMinimum = INT_MAX;
for(int i = 0; i < (int)vecOffsets.size(); i++)
{ // find the minimum number
if((false == vecOffsets[i].m_bChecked) && (RetrieveValueFromHDD(vecOffsets[i].m_llCurOffset) < nMinimum))
nMinimum = vecHDD[(int)vecOffsets[i].m_llCurOffset];
}
// start changing indices for values equivalent to nMinimum
for(int i = 0; i < (int)vecOffsets.size(); i++)
{
bool bKeepChanging = true;
for(int j = 0; j < ROWS && (true == bKeepChanging) && ((vecOffsets[i].m_llCurOffset - vecOffsets[i].m_llOffset) < ROWS); j++)
{
if(RetrieveValueFromHDD(vecOffsets[i].m_llCurOffset) == nMinimum)
vecOffsets[i].m_llCurOffset++;
else // terminate correct fragment
bKeepChanging = false;
}
if ((vecOffsets[i].m_llCurOffset - vecOffsets[i].m_llOffset) >= ROWS && (false == vecOffsets[i].m_bChecked))
{
vecOffsets[i].m_bChecked = true;
nFragments--;
}
}
std::cout << "distinct number:" << nMinimum << '\n';
nCount++;
}
std::cout << "total distinctive numbers: " << nCount;
}
void main()
{
FILE* pf;
std::string str;
long nCount = 0;
long arr[ROWS] = { 0 };
__int64 i64Offset = 0;
char pDirectoryPath[256 * 2];
// get current location
_getcwd(pDirectoryPath, ARRSIZE(pDirectoryPath));
strcat_s(pDirectoryPath, FILE_NAME);
fopen_s(&pf, pDirectoryPath, "r");
if (pf == NULL)
return;
std::vector<CPair> vecPos;
char pLine[MAX_LINE];
while (0 != fgets(pLine, MAX_LINE, pf))
{
arr[nCount] = atoi(pLine);
nCount++;
if (nCount == ROWS)
{
// create the offset array, save the start of each fragment
vecOffsets.push_back(CPair(i64Offset));
std::vector<long> vec(arr, arr + ARRSIZE(arr));
std::sort(vec.begin(), vec.end());
// continue creating the HDD array, it will hold sorted fragments.
vecHDD.insert(vecHDD.end(), vec.begin(), vec.end());
i64Offset += nCount;
nCount = 0;
}
}
FindDistinct();
fclose(pf);
}