目录树

 

7-8 目录树 (30 分)

在ZIP归档文件中,保留着所有压缩文件和目录的相对路径和名称。当使用WinZIP等GUI软件打开ZIP归档文件时,可以从这些信息中重建目录的树状结构。请编写程序实现目录的树状结构的重建工作。

输入格式:

输入首先给出正整数N(≤10​4​​),表示ZIP归档文件中的文件和目录的数量。随后N行,每行有如下格式的文件或目录的相对路径和名称(每行不超过260个字符):

  • 路径和名称中的字符仅包括英文字母(区分大小写);
  • 符号“\”仅作为路径分隔符出现;
  • 目录以符号“\”结束;
  • 不存在重复的输入项目;
  • 整个输入大小不超过2MB。

输出格式:

假设所有的路径都相对于root目录。从root目录开始,在输出时每个目录首先输出自己的名字,然后以字典序输出所有子目录,然后以字典序输出所有文件。注意,在输出时,应根据目录的相对关系使用空格进行缩进,每级目录或文件比上一级多缩进2个空格。

输入样例:

7
b
c\
ab\cd
a\bc
ab\d
a\d\a
a\d\z\

输出样例:

root
  a
    d
      z
      a
    bc
  ab
    cd
    d
  c
  b

其实开始题意有点蒙,简单来说,只有后面不带 \ 的才是文件 ,目录优先输出。

比如你看 前三个a d z其实这三个都是目录,这个目录下是没有文件的,而下一个a 其实是d目录下面的文件。所以才会有z,a这种看似不对的顺序。(目录优先度要高于文件,谨记)。

#include <bits/stdc++.h>
using namespace std;

typedef struct Node
{
    string name;
    bool mulu;
    deque<struct Node*> next;
    Node(string s, bool m)
    {
        name=s;
        mulu=m;
    }
} Node;
bool cmp(Node*n1,Node*n2)
{
    if(n1->mulu==n2->mulu)
    {
        return n1->name<n2->name;
    }
    else if(n1->mulu==true)
        return 1;
    else
        return 0;
}
void Print(Node* &root,int c)
{
    if(root->next.size()==0)
        return;
    for(int i=0; i<(root->next).size(); i++)
    {
        sort((root->next).begin(),(root->next).end(),cmp);
        for(int j=0; j<c; j++)
            cout<<"  ";
        cout<<(root->next)[i]->name<<endl;
        Print((root->next)[i],c+1);
    }
}
void Insert(Node* &root,string s)
{
    if(s=="")
        return;
    int index = -1;
     if((index=s.find_first_of('\\'))!=string::npos)//string类查不到会返回nops;
      {
          string name =s.substr(0,index);//第一个参数是下标(从那开始截取),第二个参数表示截取多少个字符
          string lefts=s.substr(index+1,s.length());//截取剩下的
          bool flag = 1;
          int j;
          for(int i=0;i<root->next.size();i++)
            {
                if( (root->next)[i]->name==name)
                {
                    flag = false;
                    j = i;
                    break;
                }
            }
            if(flag)//原来没有,新建一个
            {
                Node *p =new Node(name,1);
                (root->next).push_back(p);
                Insert(root->next.back(),lefts );
            }
            else
            {
                Insert((root->next)[j],lefts);
            }
      }
      else
      {
          bool flag = 1;
          for(int i=0;i<root->next.size();i++)
          {
              if((root->next)[i]->name==s)
              {
                  flag = 0;
                  break;
              }
          }
          if(flag)//如果没有的话
          {
              Node *p =new Node(s,0);
              root->next.push_back(p);
          }
      }
}
int main()
{
    int n;
    string s;
    cin>>n;
    Node* root =new Node("root",1);
    while(n--)
    {
        cin>>s;
        Insert(root,s);
    }
    cout<<"root\n";
    Print(root,1);
    return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值