对于大容量的数组,可以把它和一个文件绑定,内存中只缓存一些正在使用的片断。这样,数组的容量可以非常大。这是C++的一个实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class filearray {
private:
struct page {
int pageno;
int tag;
int *data;
};
FILE *fp;
int count;
int freenode;
struct page node[8];
int buf[100];
private:
class cell {
public:
int index;
filearray *ma;
int operator=(int val) {
int *ip;
ip = ma->maparray(index);
*ip = val;
return val;
}
operator int() {
int *ip;
ip = ma->maparray(index);
return *ip;
}
};
cell u;
public:
filearray(FILE *fp);
~filearray();
cell operator[](int index) {
u.index = index;
return u;
}
private:
int findlazy();
void reset_tags();
int *maparray(int index);
};
filearray::filearray(FILE *fp) :fp(fp) {
count =1;
freenode = 0xff;
memset(&node[0], 0, sizeof(struct page)*8);
for(int i=0; i<8; i++) {
node[i].pageno=-1;
}
u.index=0;
u.ma = this;
}
filearray::~filearray() {
for(int i=0; i<8; i++) {
if (node[i].pageno<0) continue;
fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
fread(buf, sizeof(int), 100, fp);
if (memcmp(buf, node[i].data, sizeof(int)*100)!=0) {
fseek(fp, node[i].pageno*100*sizeof(int),
SEEK_SET);
fwrite(node[i].data, sizeof(int), 100, fp);
}
}
fclose(fp);
}
int filearray::findlazy()
{
int i;
int lazy;
int tag;
lazy =0;
tag= node[0].tag;
for(i=1; i<8; i++) {
if( node[i].tag<tag) {
tag= node[i].tag;
lazy=i;
}
}
return lazy;
}
void filearray::reset_tags()
{
int i, j;
int index[8];
for(i=0;i<8; i++) index[i]=i;
for(i=0; i<8-1; i++) {
for(j=i+1;j<8; j++) {
int t;
if (node[index[i]].tag >node[index[j]].tag) {
t= index[j];
index[j] = index[i];
index[i]= t;
}
}
}
for(i=0; i<8; i++) {
printf("%d\t", node[index[i]].tag);
}
printf("\n");
for(i=0; i<8; i++) {
node[index[i]].tag=i;
}
count =8;
}
int *filearray::maparray(int index)
{
int i;
int pageno;
pageno = index/100;
for(i =0; i<8; i++) {
if (node[i].pageno==pageno) {
find:
node[i].tag = count++;
if( count <0) {
reset_tags();
}
return &node[i].data[index%100];
}
}
if (freenode) {
int mask;
mask=1;
for(i=0; i<8; i++) {
if (freenode &mask) {
freenode ^= mask;
node[i].pageno = pageno;
node[i].data = (int *)malloc(sizeof(int)*100);
if (node[i].data==NULL) {
printf("malloc error\n");
exit(0);
}
printf("use free node %d\n", i);
goto find;
}
mask <<=1;
}
}
i = findlazy();
fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
fread(buf, sizeof(int), 100, fp);
if (memcmp(buf, node[i].data, sizeof(int)*100)!=0) {
fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
fwrite(node[i].data, sizeof(int), 100, fp);
}
node[i].pageno = pageno;
fseek(fp, node[i].pageno*100*sizeof(int), SEEK_SET);
fread(node[i].data, sizeof(int), 100, fp);
goto find;
}
int main()
{
int i;
int val;
char *name;
FILE *fp;
name = "array.dat";
fp = fopen(name, "w+b");
if (!fp) {
printf("can not open %s\n", name);
exit(0);
}
filearray arr(fp);
for(i=0; i<100000; i++) {
arr[i] = 10000000+ i;
}
for(i=0; i<100/2; i++) {
val = arr[((49-i)*2000)];
printf("%d\n", val);
}
arr[100]=200;
arr[200]= arr[100]+4;
printf("%d, %d", int(arr[100]),int(arr[100]*arr[200]));
return 0;
}