【题目链接】
OpenJudge NOI 2.2 1777:文件结构“图”
【题目考点】
1. 递归
【解题思路】
先将每行数据读入,保存在一个vector类对象dataSet中(也可以保存在数组中),当读入一行*(星号)时,dataSet中已保存了一组数据,处理并输出这组数据。
对每组数据的处理方法为:
设函数showDir,参数为当前目录名字,以及缩进层级。
先声明multiset类型的ms,用于对文件名作排序。
从前向后遍历dataSet中的数据
- 如果这一行数据是目录名,则递归调用showDir,该子目录的缩进层级加1,输出该目录中的情况。
- 如果这一行数据是文件名,则将该文件加入ms。
最后遍历输出ms中的所有文件名。由于multiset原理是红黑树,遍历multiset类对象即可得到升序序列。
(这里也可以将文件名都先加入数组,然后对数组排序)
【题解代码】
写法1:使用C++ STL容器
#include <bits/stdc++.h>
using namespace std;
vector<string> dataSet;//数据集
int di;//di为dataSet中的下标
void printWithTab(string s, int tab)//在缩进层级为tab的情况下输出s
{
for(int i = 1; i <= tab; i++)
cout << "| ";
cout << s << endl;
}
void showDir(string dirName, int tabNum)//输出文件夹,名字为dirName,缩进层级:tabNum
{
multiset<string> ms;//多重集合ms,原理是红黑树,可以用于对文件名做二叉树排序
printWithTab(dirName, tabNum);//输出文件夹名
string s;
while(di < dataSet.size())
{
s = dataSet[di++];
if(s[0] == 'd')
showDir(s, tabNum+1);
else if(s[0] == 'f')
ms.insert(s);
else if(s[0] == ']')
break;
}
for(string fileName : ms)//输出ms中的文件名,for冒号遍历输出自然会得到升序序列
printWithTab(fileName, tabNum);
}
int main()
{
string s;
int dataSetNum = 1;
while(cin >> s)
{
if(s[0] == '#')
break;
else if(s[0] == '*')
{
cout << "DATA SET " << dataSetNum << ':' << endl;
dataSetNum++;
showDir("ROOT", 0);
di = 0;
dataSet.clear();
cout << endl;
}
else
dataSet.push_back(s);
}
return 0;
}
写法2:C风格
#include <cstdio>
#include <cstring>
using namespace std;
#define N 35
char dataSet[N][1005];//数据集
int di, dn;//dn:dataSet中元素个数
void printWithTab(char s[], int tab)//在缩进层级为tab的情况下输出s
{
for(int i = 1; i <= tab; i++)
printf("| ");
printf("%s\n", s);
}
void swapStr(char a[], char b[])
{
char c[N];
strcpy(c, a);
strcpy(a, b);
strcpy(b, c);
}
void showDir(char dirName[], int tabNum)//输出文件夹,名字为dirName,缩进层级:tabNum
{
char fileNames[N][N];
int fi = 0;//di:dataSet中的下标
printWithTab(dirName, tabNum);//输出文件夹名
while(di < dn)
{
if(dataSet[di][0] == 'd')
{
di++;
showDir(dataSet[di-1], tabNum+1);
}
else if(dataSet[di][0] == 'f')
{
strcpy(fileNames[fi], dataSet[di]);
for(int j = fi; j > 0; j--)//插入排序
{
if(strcmp(fileNames[j], fileNames[j-1]) < 0)
swapStr(fileNames[j], fileNames[j-1]);
else
break;
}
fi++;
di++;
}
else if(dataSet[di][0] == ']')
{
di++;
break;
}
}
for(int i = 0; i < fi; ++i)
printWithTab(fileNames[i], tabNum);
}
int main()
{
char s[N];
int dataSetNum = 1;
while(scanf("%s", s) != EOF)
{
if(s[0] == '#')
break;
else if(s[0] == '*')
{
printf("DATA SET %d:\n", dataSetNum);
dataSetNum++;
showDir("ROOT", 0);
printf("\n");
di = dn = 0;
}
else
strcpy(dataSet[dn++], s);
}
return 0;
}