ZOJ-1635(模擬pstree)

模擬打印文件樹,難點在文件夾的開閉,如果僅僅將子文件縮進,則問題很簡單,遞歸即可,題目要求顯示文件夾的開閉(用'|'),所以直接遞歸打印不能解決(因爲可能需要在前面打印'|'),這裏我選擇將需要打印的所有符號保存在一個緩衝區char型數組裏,修改緩衝區再打印緩衝區

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
using namespace std;
#define MAX_NODE	200
#define MAX_ROW		12
#define	MAX_COL		200
/*
|_#/usr[24]
        |_*mark[17]
        |       |_hw.c[3]
        |       |_*course[13]
        |               |_aa.txt[12]
        |_*alex[6]
                |_hw.c[5]
*/
struct Node
{
	string name;
	size_t size;
	bool   isDir;
	int    printRow;
	Node*  parent;
	vector<Node*> children;
} nodes[MAX_NODE], *root;
int nex;
Node* newNode(const string& s, size_t u, Node* f)
{
	Node* p = nodes + nex++;
	p->name = s;
	p->size = u;
	p->isDir = s[0] == '*';
	p->parent = f;
	p->children.clear();
	return p;
}

size_t walk(Node* p)
{
	if(p->isDir){
		vector<Node*>& v = p->children;
		for(int i = 0, n = v.size(); i < n; ++i){
			p->size += walk(v[i]);
		}
	}
	return p->size;
}

char graph[MAX_ROW][MAX_COL];
void gls(Node* p, int level, int& row)
{
// step 1: print this node
	//figure out how many indent spaces are there
	int offset = level << 3;
	//leave indent spaces in front
	if(p->parent){
		for(int i = p->parent->printRow+1; i <= row; ++i){
			graph[i][offset] = '|';
		}
	}
	else graph[row][offset] = '|';
	//print leading char
	graph[row][offset+1] = '_';
	//print "name[size]"
	int n = sprintf(&graph[row][offset+2], "%s[%u]", p->name.c_str(), p->size);
	//recover last space rewritten by sprintf
	graph[row][offset+2+n] = ' ';
	//mark the printing row
	p->printRow = row++;

// step 2: print all children
	if(p->isDir){
		vector<Node*>& v = p->children;
		for(int i = 0, n = v.size(); i < n; ++i){
			gls(v[i], level + 1, row);
		}
	}
}
void rtrim(int n)
{
	int i, j;
	for(i = 0; i < n; ++i){
		for(j = MAX_COL - 1; graph[i][j] == ' '; --j) ;
		graph[i][j+1] = '\0';
	}
}
void ls()
{
// step 0: init graph array
	memset(graph, ' ', sizeof(graph));
// step 1: set print graph array
	walk(root);
	int row = 0;
	gls(root, 0, row);
//step 2: trim graph array
	rtrim(row);
//step 3: print the graph
	for(int i = 0; i < row; ++i) puts(graph[i]);
}

void inputChildren(Node* fa)
{
	string name;
	size_t size;
	while(cin.get() != '(');
	while(cin >> name, name != ")"){
		cin >> size;
		fa->children.push_back(newNode(name, size, fa));
	}
}
bool input()
{
	string name;
	size_t size;
	if(cin >> name >> size, !cin) return false;
	nex = 0;
	root = newNode(name, size, NULL);

	queue<Node*> q;
	q.push(root);
	while(!q.empty()){
		for(int n = q.size(); n--; ){
			Node* p = q.front(); q.pop();
			if(p->isDir){
				inputChildren(p);
				vector<Node*>& v = p->children;
				for(int i = 0, n = v.size(); i < n; ++i){
					q.push(v[i]);
				}
			}
		}
	}
	return true;
}

int main()
{
	while(input()) ls();
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章