题目: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;
}