POJ-3856(模拟构造目录树)

题目:http://poj.org/problem?id=3856

分析:根据命令输出构造出目录树,需要注意的地方:(1)cd 后跟的目录可能之前没有出现过;(2)根据deltree作为case的最后一行输入,而不是题目中说的每个case之后会跟一个空行(sample input里第3个和第4个case之间就没有空行)


#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <map>
#include <set>
#include <string>
using namespace std;

struct Directory{
	int file_size;
	set<Directory*> subdirectory;

	Directory(): file_size(0){}
	void AddDir(Directory* pSub){
		subdirectory.insert(pSub);
	}
	void AddFile(int size){
		file_size += size;
	}
	int TotalSize()const{
		int sum = file_size;
		set<Directory*>::iterator it = subdirectory.begin();
		for(; it != subdirectory.end(); ++it) sum += (*it)->TotalSize();
		return sum;
	}
};

Directory* GetOrCreate(map<string, Directory*>& path_dir_map, const string& path)
{
	map<string, Directory*>::iterator it = path_dir_map.find(path);
	if(it == path_dir_map.end()){
		//printf("mkdir: %s\n", path.c_str());
		Directory* pDir = new Directory;
		it = path_dir_map.insert(map<string, Directory*>::value_type(path, pDir)).first;
	}
	//else printf("%s already exist\n", path.c_str());
	return it->second;
}
void Mkdir(map<string, Directory*>& path_dir_map, const string& path)
{
	Directory* pDir = GetOrCreate(path_dir_map, "\\");
	for(size_t pos = path.find('\\', 1); pos != string::npos; pos = path.find('\\', pos+1)){
		Directory* pSub = GetOrCreate(path_dir_map, path.substr(0, pos+1));
		pDir->AddDir(pSub);
		pDir = pSub;
	}
}

int main()
{
	bool exit = false, done;
	char line[255] = {' '}, name[255];
	string cur_dir;
	map<string, Directory*> path_dir_map;
	map<string, Directory*>::iterator it;
	while(!exit){
		cur_dir = "\\";
		done = false;
		while(!done){
			//input next cmd
			if(line[0] == '\0' || isspace(line[0])){
				gets(line);
				continue;
			}
			if(line[1] == 'e'){
				exit = true;
				break;
			}
			//execute cmd
			//printf("execute %s\n", line+1);
			switch(line[2]){
				case 'd':
					//>cd
					{
						sscanf(line+3, "%s", name);
						if(name[0] == '\\'){
							//absolute
							cur_dir = name;
						}
						else if(name[0] == '.'){
							//cd ..
							if(cur_dir != "\\"){
								size_t pos = cur_dir.rfind('\\', cur_dir.size() - 2);
								cur_dir.erase(pos + 1);
							}
						}
						else{
							//relative
							cur_dir += name;
						}
						if(*cur_dir.rbegin() != '\\') cur_dir.push_back('\\');
						Mkdir(path_dir_map, cur_dir);
						line[0] = ' ';
					}
					break;
				case 'i':
					//>dir
					{
						Directory* pDir = GetOrCreate(path_dir_map, cur_dir);
						for(gets(line); line[0] != '>'; gets(line)){
							//printf("%s under %s\n", line, cur_dir.c_str());
							string s(line);
							size_t pos = s.find(' ');
							if(pos == string::npos){
								//directory
								Directory* pSub = GetOrCreate(path_dir_map, cur_dir + s + '\\');
								pDir->AddDir(pSub);
							}
							else{
								//file
								pDir->AddFile(atoi(line + pos));
							}
						}
					}
					break;
				case 'e':
					//deltree
					{
						string s(line);
						size_t pos = s.find(' ');
						sscanf(line + pos, "%s", name);
						if(name[0] != '\\'){
							s = cur_dir + name;
						}
						else{
							s = name;
						}
						if(*s.rbegin() != '\\') s.push_back('\\');
						Directory* pDir = GetOrCreate(path_dir_map, s);
						printf("%d\n", pDir->TotalSize());
						line[0] = ' ';
						done = true;
					}
					break;
			}
		}

		for(it = path_dir_map.begin(); it != path_dir_map.end(); ++it) delete it->second;
		path_dir_map.clear();
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值