Skip to content

1337: MemoryRiver

题目

题目描述

Description

本题中,需要实现一个包含空间回收的文件读写类

Where the north wind meets the sea

There's a river full of memory

Sleep, my darling, safe and sound

For in this river all is found

—— All is Found

文件存储操作是编程的重要部分,其分为ASCII文件存储和二进制文件存储。文件其实是一块白纸,交由你创作出块状、链状、树状的画作,以及本题中需要实现的MemoryRiver类。

MemoryRiver类是为了方便对文件的操作而封装了一些操作。该类的功能有

  • 与一个文件名(string)绑定
  • 往文件中写入一个intT类型对象
  • 往文件中读取一个intT类型对象(T的大小大于int)
  • 删除并回收一块空间。

请实现一个类模板MemoryRiver.hpp,来实现文件的读写。

该类模板的声明为

c++ template<class T, int info_len = 2> class MemoryRiver;

其中,T是需要存储的原子对象的类,info_len是存储文件头部预留出来的int的个数(1_base)。

MemoryRiver的存储策略为在文件首预留出 info_lenint作为存储一些参数的空间,这些intinitialise()函数种被初始化为0。

请完成MemoryRiver.hpp内的代码:

MemoryRiver.hpp

```c++

ifndef BPT_MEMORYRIVER_HPP

define BPT_MEMORYRIVER_HPP

include

using std::string; using std::fstream; using std::ifstream; using std::ofstream;

template class MemoryRiver { private: / your code here / fstream file; string file_name; int sizeofT = sizeof(T); public: MemoryRiver() = default;

MemoryRiver(const string& file_name) : file_name(file_name) {}

void initialise(string FN = "") {
    if (FN != "") file_name = FN;
    file.open(file_name, std::ios::out);
    int tmp = 0;
    for (int i = 0; i < info_len; ++i)
        file.write(reinterpret_cast<char *>(&tmp), sizeof(int));
    file.close();
}

//读出第n个int的值赋给tmp,1_base
void get_info(int &tmp, int n) {
    if (n > info_len) return;
    /* your code here */
}

//将tmp写入第n个int的位置,1_base
void write_info(int tmp, int n) {
    if (n > info_len) return;
    /* your code here */
}

//在文件合适位置写入类对象t,并返回写入的位置索引index
//位置索引意味着当输入正确的位置索引index,在以下三个函数中都能顺利的找到目标对象进行操作
//位置索引index可以取为对象写入的起始位置
int write(T &t) {
    /* your code here */
}

//用t的值更新位置索引index对应的对象,保证调用的index都是由write函数产生
void update(T &t, const int index) {
    /* your code here */
}

//读出位置索引index对应的T对象的值并赋值给t,保证调用的index都是由write函数产生
void read(T &t, const int index) {
    /* your code here */
}

//删除位置索引index对应的对象(不涉及空间回收时,可忽略此函数),保证调用的index都是由write函数产生
void Delete(int index) {
    /* your code here */
}

};

endif //BPT_MEMORYRIVER_HPP

```

tips:

设置本题的目的之一是为bookstore大作业作准备

二进制文件的读写(可参考https://en.cppreference.com/w/cpp/io/basic_fstream 等资料)

c++ //T类型的对象t的二进制文件读写 file.write(reinterpret_cast<char *>(&t), sizeof(T)); file.read(reinterpret_cast<char *>(&t), sizeof(T)); //将指针移动到[文件头指针+offset]处 file.seekp(offset);

可以使用文件(多)链表的思想来实现空间回收。

也可以用类似内存池的思想,多开一个文件进行管理。

可以隐式的增加文件头部的info_len的长度供自己使用,但是需要在get_info和write_info时作一个转换的映射避免冲突

本题未对原子化操作做出要求,但在大作业中推荐在每个函数调用前打开文件,调用后关闭文件。

评测的文件数量限制为20,但最好不要超过2个文件

$2\le infolen$

Oops! 本题目还没有解答!

助教老师们编题的速度,已经超过了解题的速度!

OJ翻了一新,但本解答集还大多用的是2017-2019级,甚至更早的同学们贡献的答案。

如果你已经AC了,可以的话,请您参考添加页面,与大家一起分享你的题解!