一个有关超大数组记录访问的问题

前几天的一个面试题。貌似这个问题网上也有不少人热议。我的思路是认为这个问题与内存分配管理类似,以下是我的解决方法。

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;
}

用结构体数组记录车辆违停信息的设计应该考虑以下几个方面: 1. 结构体定义(struct):首先,定义一个包含关键信息的结构体,如`VehicleViolation`。可能包括的字段有: - 车牌号(std::string plateNumber) - 违停车位编号(int parkingLotID) - 违规时间(time_t violationTime 或 std::chrono::time_point) - 违规类型(enum ViolationType) - 状态(bool isResolved)表示是否已处理 ```cpp struct VehicleViolation { std::string plateNumber; int parkingLotID; time_t violationTime; ViolationType type; bool isResolved; }; ``` 2. 动态数组(std::vector):由于车辆违停信息的数量可能会变化,所以使用动态大小的`std::vector<VehicleViolation>`更合适。 3. 插入和查询功能:提供适当的函数来添加新的违停记录(push_back)以及查找特定违章记录(如根据车牌号、车位ID等): ```cpp void addViolation(VehicleViolation& newViolation); VehicleViolation* findViolationByPlate(const std::string& plateNumber); ``` 4. 数据排序:如果你希望按时间顺序管理违章记录,可以对数组进行排序,例如使用`std::sort`。 5. 内存管理:确保正确管理内存,比如当违章记录被处理时,更新`isResolved`并清除不再需要的记录。 6. 性能优化:对于频繁的操作,考虑使用哈希表或其他数据结构来加快查找速度,但要注意空间复杂度。 7. 读写权限控制:如果是多个用户共享同一数据,要考虑并发访问的情况,可能需要加锁或者其他并发控制机制。 8. 易于扩展:为未来可能增加的新属性留出空间,如罚款金额、处理人员等。 ```cpp void printViolations(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值