poj1760 Disk Tree

先上題目:

3:Disk Tree
查看 提交 統計 提問
總時間限制: 1000ms 內存限制: 65536kB
描述
Hacker Bill has accidentally lost all the information from his workstation's hard drive and he has no backup copies of its contents. He does not regret for the loss of the files themselves, but for the very nice and convenient directory structure that he had created and cherished during years of work. Fortunately, Bill has several copies of directory listings from his hard drive. Using those listings he was able to recover full paths (like "WINNT\SYSTEM32\CERTSRV\CERTCO~1\X86") for some directories. He put all of them in a file by writing each path he has found on a separate line. Your task is to write a program that will help Bill to restore his state of the art directory structure by providing nicely formatted directory tree.
輸入
The first line of the input file contains single integer number N (1 <= N <= 500) that denotes a total number of distinct directory paths. Then N lines with directory paths follow. Each directory path occupies a single line and does not contain any spaces, including leading or trailing ones. No path exceeds 80 characters. Each path is listed once and consists of a number of directory names separated by a back slash ("\").

Each directory name consists of 1 to 8 uppercase letters, numbers, or the special characters from the following list: exclamation mark, number sign, dollar sign, percent sign, ampersand, apostrophe, opening and closing parenthesis, hyphen sign, commercial at, circumflex accent, underscore, grave accent, opening and closing curly bracket, and tilde ("!#$%&'()-@^_`{}~").
輸出
Write to the output file the formatted directory tree. Each directory name shall be listed on its own line preceded by a number of spaces that indicate its depth in the directory hierarchy. The subdirectories shall be listed in lexicographic order immediately after their parent directories preceded by one more space than their parent directory. Top level directories shall have no spaces printed before their names and
shall be listed in lexicographic order. See sample below for clarification of the output format.
樣例輸入
7
WINNT\SYSTEM32\CONFIG
GAMES
WINNT\DRIVERS
HOME
WIN\SOFT
GAMES\DRIVERS
WINNT\SYSTEM32\CERTSRV\CERTCO~1\X86
樣例輸出
GAMES
 DRIVERS
HOME
WIN
 SOFT
WINNT
 DRIVERS
 SYSTEM32
  CERTSRV
   CERTCO~1
    X86
  CONFIG
來源
Northeastern Europe 2000


數據結構較爲直觀:建立一個森林,然後對森林中的每一棵樹進行先根遍歷,打印結點信息(包含縮進和文字)。但是,題目要求根據字典順序輸出,這就要求樹先根遍歷輸出的結點恰好也是按照字典順序的。怎麼做?一種辦法是對輸入的文本進行排序,這樣在建立樹的時候,結點的先根遍歷順序也是按照字典順序的。


參考POJ1760,我瞭解到stl map的一條重要性質:在插入key-value對時,map總是可以保證key的有序性。下面我把目前對map的理解總結如下:

  1. map是一個容器,用於存放key-value對;key和value的數據類型可任意定義;對於容器中的某個元素p,(p->first)也就是key,(p->second)也就是value。
  2. map容器中元素的key值是唯一的,要麼存在(只出現一次),要麼不存在。可以用“map容器名.count(key)”判斷,count函數的返回值只可能是0或1。
  3. map容器在插入元素(key-value對)時,保持key的有序性。
因此,數據結構可進一步描述如下:
  1. 申請一組容器map<string, int> m[MAXNODE];m[i]儲存親兄弟結點;特別地,m[0]儲存森林中所有樹的樹根結點。
  2. 對於結點node=m[i][key],node->first爲結點的名稱(數據類型爲string);node->second爲此結點直系後代的“指針”(數據類型爲int),即此結點所有的直系後代儲存在m[node->second]中。
  3. 由map的性質,m[i]中所有元素的key總是保持有序。
於是題目中樣例的存儲結構如下圖:


代碼清單:
#include <string>
#include <cstring>
#include <cstdio>
#include <map>
using namespace std;

#define MAXNODE 20000	//輸入文本每行最多40個結點,40*500
#define MAXLEN 85
#define MAXWORD 45

map<string, int> m[MAXNODE];

void preOder_traversal(int midx, int indentation)
{
	for (map<string, int>::iterator i=m[midx].begin(); i!=m[midx].end(); ++i)
	{
		for (int i=0; i<indentation; ++i)	printf(" ");
		printf("%s\n", (i->first).c_str());

		preOder_traversal(i->second, indentation+1);
	}
}

int main()
{
	//freopen("D:\\in.txt", "r", stdin);
	//freopen("D:\\out.txt", "w", stdout);

	int n, i, j, midx, midx_counter=0;
	char str[MAXLEN];
	int word_init[MAXWORD];
	string current_str;

	scanf("%d", &n);

	while (n--)
	{
		scanf("%s", str);

		//下面把str中的單詞分割開來
		word_init[0]=0;
		j=1;
		for (i=0; str[i]; ++i)	//0是空字符'\0'的十進制值
		{
			if(str[i]=='\\')
			{
				str[i]=0;
				word_init[j++]=i+1;	//第j個單詞從str[i+1]開始
			}
		}

		midx=0;	//從樹根開始
		for (i=0; i<j; ++i)	//有j個單詞
		{
			current_str=str+word_init[i];

			if(!m[midx].count(current_str))	//新結點
			{
				m[midx][current_str]=(++midx_counter);
			}

			midx=m[midx][current_str];
		}
	}

	preOder_traversal(0, 0);

	return 0;
}




發佈了50 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章