OpenJudge NOI 2.2 1777:文件结构“图”

【题目链接】

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;
}

猜你喜欢

转载自blog.csdn.net/lq1990717/article/details/128720878