前几天的一个面试题。貌似这个问题网上也有不少人热议。我的思路是认为这个问题与内存分配管理类似,以下是我的解决方法。
PS:虽然我这个不能解决无限大个数组,但在64位机上至少是不会有任何问题了。其实这个还有很多能优化的地方,既然它只是个题,那就这样吧!
原问题:
假设存在一个超大数组,数组分配出来未初始化,现在不希望对数组进行初始化,但需要在访问数组某个元素的时候知道这个位置上的数是否是第一次被访问.判断过程需要是O(1)复杂度.如果存在预处理,预处理也应该是O(1)复杂度.可以假设存在无穷大的空间.
#include "stdio.h"
#include <iostream>
#define MEMORY_BLOCK_SIZE 4096 /*4KB*/
typedef unsigned long long ulonglong64;
typedef struct{
//visite mark struct
int mark[MEMORY_BLOCK_SIZE];
} MemIndex_L0;
typedef struct{
//visite index struct
MemIndex_L0 *index[MEMORY_BLOCK_SIZE];
}MemIndex_L1;
typedef struct{
//visite index struct
MemIndex_L1 *index[MEMORY_BLOCK_SIZE];
}MemIndex_L2;
typedef struct{
//visite index struct
MemIndex_L2 *index[MEMORY_BLOCK_SIZE];
}MemIndex_L3;
typedef struct{
//visite index struct
MemIndex_L3 *index[MEMORY_BLOCK_SIZE];
}MemIndex_L4;
typedef struct{
//visite index struct
MemIndex_L4 *index[MEMORY_BLOCK_SIZE];
}MemIndex_L5;
//memory index
static MemIndex_L5 *memSystem64Bit= NULL;
void memIndexInitial()
{
if(memSystem64Bit == NULL)
{
memSystem64Bit= new MemIndex_L5;
memset(memSystem64Bit,0, sizeof(MemIndex_L5));
}
}
int memGetVisited(ulonglong64 addr)
{
int result;
MemIndex_L0 *pMem_L0;
MemIndex_L1 *pMem_L1;
MemIndex_L2 *pMem_L2;
MemIndex_L3 *pMem_L3;
MemIndex_L4 *pMem_L4;
MemIndex_L5 *pMem_L5;
int index_L5, index_L4, index_L3, index_L2, index_L1, index_L0;
index_L0= 0x0000000004FF & (addr);
index_L1= 0x0000000004FF & (addr >> 12);
index_L2= 0x0000000004FF & (addr >> 24);
index_L3= 0x0000000004FF & (addr >> 36);
index_L4= 0x0000000004FF & (addr >> 48);
index_L5= 0x0000000004FF & (addr >> 60);
//get MemIndex_L5
//if(memSystem64Bit == NULL) memIndexInitial();
pMem_L5= memSystem64Bit;
pMem_L4= pMem_L5->index[index_L5];
if(pMem_L4 == NULL) return NULL;
pMem_L3= pMem_L4->index[index_L4];
if(pMem_L3 == NULL) return NULL;
pMem_L2= pMem_L3->index[index_L3];
if(pMem_L2 == NULL) return NULL;
pMem_L1= pMem_L2->index[index_L2];
if(pMem_L1 == NULL) return NULL;
pMem_L0= pMem_L1->index[index_L1];
if(pMem_L0 == NULL) return NULL;
result= pMem_L0->mark[index_L0];
return result;
}
int memSetVisited(ulonglong64 addr)
{
int index_L5, index_L4, index_L3, index_L2, index_L1, index_L0;
index_L0= 0x0000000004FF & (addr);
index_L1= 0x0000000004FF & (addr >> 12);
index_L2= 0x0000000004FF & (addr >> 24);
index_L3= 0x0000000004FF & (addr >> 36);
index_L4= 0x0000000004FF & (addr >> 48);
index_L5= 0x0000000004FF & (addr >> 60);
MemIndex_L0 *pMem_L0;
MemIndex_L1 *pMem_L1;
MemIndex_L2 *pMem_L2;
MemIndex_L3 *pMem_L3;
MemIndex_L4 *pMem_L4;
MemIndex_L5 *pMem_L5;
//get MemIndex_L5
//if(memSystem64Bit == NULL) memIndexInitial();
pMem_L5= memSystem64Bit;
pMem_L4= pMem_L5->index[index_L5];
if(pMem_L4 == NULL)
{
pMem_L4= new MemIndex_L4;
memset(pMem_L4,0, sizeof(MemIndex_L4));
pMem_L5->index[index_L5]= pMem_L4;
}
pMem_L3= pMem_L4->index[index_L4];
if(pMem_L3 == NULL)
{
pMem_L3= new MemIndex_L3;
memset(pMem_L3,0, sizeof(MemIndex_L3));
pMem_L4->index[index_L4]= pMem_L3;
}
pMem_L2= pMem_L3->index[index_L3];
if(pMem_L2 == NULL)
{
pMem_L2= new MemIndex_L2;
memset(pMem_L2,0, sizeof(MemIndex_L2));
pMem_L3->index[index_L3]= pMem_L2;
}
pMem_L1= pMem_L2->index[index_L2];
if(pMem_L1 == NULL)
{
pMem_L1= new MemIndex_L1;
memset(pMem_L1,0, sizeof(MemIndex_L1));
pMem_L2->index[index_L2]= pMem_L1;
}
pMem_L0= pMem_L1->index[index_L1];
if(pMem_L0 == NULL)
{
pMem_L0= new MemIndex_L0;
memset(pMem_L0,0, sizeof(MemIndex_L0));
pMem_L1->index[index_L1]= pMem_L0;
}
pMem_L0->mark[index_L0]= 1;
return 1;
}
int main()
{
memIndexInitial();
memSetVisited(1000);
memSetVisited(1000000);
memSetVisited(1);
printf("%d %d %d %d %d %d",memGetVisited(1),memGetVisited(2),memGetVisited(1000),memGetVisited(10000),memGetVisited(100000),memGetVisited(1000000));
getchar();
return 0;
}