给你一串路径,譬如:
a\b\c
a\d\e
b\cst
d\
你把这些路径中蕴含的目录结构给画出来,子目录直接列在父目录下面,并比父目录的首字符向右缩两个空格,就像这样:
a
b
c
d
e
b
cst
d
注:同一级的需要按字母顺序排列,不能乱。
每个测试案例第一行为一个正整数n(n<=10)表示有n个路径,当n为0时,测试结束,接下来有n行,每行有一个字串表示一个路径,长度小于50。
输出目录结构,每一个测试样例的输出紧跟一个空行。
4 a\b\c a\d\e b\cst d\ 0
a b c d e b cst d
using namespace std; #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <algorithm> #include <set> int main(){ int n; while(scanf("%d", &n) != EOF and n != 0){ vector< vector <string> > root; while(n--){ string temp; cin>>temp; vector<string> tmp; while(temp.find('\\') != temp.npos){ tmp.push_back(temp.substr(0, temp.find('\\'))); temp = temp.substr(temp.find('\\')+1, temp.size()); } if(!temp.empty())tmp.push_back(temp); root.push_back(tmp); } sort(root.begin(), root.end()); for(int i(0);i<root.size();++i){ string key = root[i][0]; cout<<root[i][0]<<endl; while(i < root.size() and key == root[i][0]){ int level = 1; for(int j(1);j<root[i].size();++j){ for(int k(0);k<level;k++)cout<<" "; cout<<root[i][j]<<endl; level++; } ++i; } --i; } } }
#include <iostream>
while True: try: num = int(input()) if not num: break trees = [] for i in range(num): trees.append(input().strip('\\').split('\\')) trees.sort() #先把树进行排序 #初始化一个未在目录出现的字符当做上一个目录 lastSign = ['#','#'] for i in range(num): beginIndex = 0 #该目录开始输出的子目录索引 blackNum = 0 #输出空格数 while beginIndex < len(trees[i]) and beginIndex < len(lastSign) and trees[i][beginIndex] == lastSign[beginIndex]: blackNum += 2 #每增加一层加两个索引 beginIndex += 1 for j in range(beginIndex, len(trees[i])): print(" "*blackNum + trees[i][j]) blackNum += 2 lastSign = trees[i] print() except Exception: break
利用二维数组的办法,用一个vector数组,数组中每个元素是一个vector<string>数组,存放了每行的各目录,如 a\b\c, 则vector<string> 数组中存放的是 a b c 三个string。
最后存放的结果:
a\b\c
a\d\e
b\cst
d\
{{a, b, c},
{a, d, e},
{b, cst}
{d}
}
当打印出第一行外每行的目录时,判断与前一行是否有相同的根目录,如果有,找到第一个不同的目录,开始打印,它对应的该行的下标控制它前面有多少缩进。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
vector<string> v, vs;
vector< vector<string> > ve;
while(cin>>n)
{
string str;
if(n==0) return 0;
v.clear(); //存放初始的所有行
for(int i = 0; i<n; i++)
{
cin>>str;
while(str[str.length()-1]!='\\') str+='\\'; //对每行进行处理,处理成最后有\字母的路径形式
v.push_back(str);
}
sort(v.begin(), v.end()); //排序
ve.clear(); //二维数组初始化
for(int i = 0; i<v.size(); i++)
{
int begin = 0, end = 0;
vs.clear(); //每个一维数组初始化
while((end = v[i].find("\\", begin))!=string::npos){
vs.push_back(v[i].substr(begin, end-begin));
begin=end+1;
}
ve.push_back(vs); //存放进二维数组中
}
for(int i = 0; i<n; i++)
{
if(i>0 && ve[i][0] == ve[i-1][0]) //与前一个目录有相同的根目录
{
int j = 1;
while(j<ve[i].size() && ve[i][j]==ve[i-1][j]) j++; //找到第一个不同的目录
for(; j<ve[i].size(); j++)
{
for(int k = 0; k<j; k++)
cout<<" "; //j是该目录在该路径中的下标,控制缩进的次数
cout<<ve[i][j]<<endl;
}
}
else{
for(int j = 0; j<ve[i].size(); j++)
{
for(int k = 0; k<j; k++)
cout<<" ";
cout<<ve[i][j]<<endl;
}
}
}
cout<<endl; //每个测试用例最后都有一个空行
}
return 0;
}
10
N\W\L\R\B\B\M\Q\B\H\C\D\A\R\Z\O\W\K\K\Y
H\I\D\D\Q\S\C\D\X\R\J\M\O\W\F\R\X\S\J\Y\
B\L\D\B\E\F\S\A\R\C\B\Y\N\E\C\D\Y\G\G\X\
X\P\K\L\O\R\E\L\L\N\M\P\A\P\Q\F\W\K\H\O\
P\K\M\C\O\Q\H\N\W\N\K\U\E\W\H\S\Q\M\G\B\
B\U\Q\C\L\J\J\I\V\S\W\M\D\K\Q\T\B\X\I\X\
M\V\T\R\R\B\L\J\P\T\N\S\N\F\W\Z\Q\F\J\M\
A\F\A\D\R\R\W\S\O\F\S\B\C\N\U\V\Q\H\F\F\
B\S\A\Q\X\W\P\Q\C\A\C\E\H\C\H\Z\V\F\R\K\
M\L\N\O\Z\J\K\P\Q\P\X\R\J\X\K\I\T\Z\Y\X\
A
F
A
D
R
R
W
S
O
F
S
B
C
N
U
V
Q
H
F
F
B
L
D
B
E
F
S
A
R
C
B
Y
N
E
C
D
Y
G
G
X
S
A
Q
X
W
P
Q
C
A
C
E
H
C
H
Z
V
F
R
K
U
Q
C
L
J
J
I
V
S
W
M
D
K
Q
T
B
X
I
X
H
I
D
D
Q
S
C
D
X
R
J
M
O
W
F
R
X
S
J
Y
M
L
N
O
Z
J
K
P
Q
P
X
R
J
X
K
I
T
Z
Y
X
V
T
R
R
B
L
J
P
T
N
S
N
F
W
Z
Q
F
J
M
N
W
L
R
B
B
M
Q
B
H
C
D
A
R
Z
O
W
K
K
Y
P
K
M
C
O
Q
H
N
W
N
K
U
E
W
H
S
Q
M
G
B
X
P
K
L
O
R
E
L
L
N
M
P
A
P
Q
F
W
K
H
O
#include<iostream>#include<cstring> #include<vector> #include<algorithm> using namespace std; struct Node{ Node(char tch[]){ strcpy(ch,tch); layer = -1; } Node(char tch[],int lay){ strcpy(ch,tch); layer = lay; } char ch[50]; int layer; vector<Node*> vec; }; void sortWholeTree(Node * r){ vector<Node*>::iterator it = r->vec.begin(); vector<Node*>::iterator it1 = r->vec.begin(); vector<Node*>::iterator it2 = r->vec.begin(); int cnt = 0; for(it1 = r->vec.begin();it1!=r->vec.end();it1++){//自己写bubble,美滋滋 for(it2 = r->vec.begin();it2!=r->vec.end()-1;){ if(strcmp((*it2)->ch,(*(it2+1))->ch)>0) swap(*it2,*(it2+1)); else it2++;//这里很重要,swap之后其实已经加一了 } } for(it = r->vec.begin();it!=r->vec.end();it++) sortWholeTree(*it); } Node* searchOneLayer(Node * r,char tgtch[]){ vector<Node*>::iterator it = r->vec.begin(); for(;it!=r->vec.end();it++){ if(strcmp((*it)->ch,tgtch)==0){ return *it; } } return NULL; } void Print(Node *r){ vector<Node*>::iterator it = r->vec.begin(); for(;it!=r->vec.end();it++){ for(int i=0;i<(*it)->layer;i++){ cout<<" "; } cout<<(*it)->ch<<endl; Print(*it); } } int main (){ //freopen("1.txt","r",stdin); int n; while(cin>>n&&(n)){ Node *root = new Node("root"); getchar(); for(int i=0;i<n;i++){ string str; char tmp[50]; getline(cin,str); int cnt = 0; Node *lastNode = root; for(int j=0;j<str.size();j++){//处理一行 if(str[j]!='\\') {tmp[cnt++] = str[j];} if(str[j]=='\\'||j==str.size()-1){ tmp[cnt++] = '\0'; //cout<<"取 "<<tmp<<endl; Node *nowNode; if((nowNode=searchOneLayer(lastNode,tmp))==NULL){ //cout<<" 没有"<<endl; Node *ptr = new Node(tmp,lastNode->layer+1); lastNode->vec.push_back(ptr); //cout<<" 挂在了"<<lastNode->ch<<endl; lastNode = ptr; //这个很重要,last变成了现在新的,便于继续寻找 }else{ //cout<<" 有"<<endl; lastNode = nowNode; } cnt = 0; memset(tmp,0,sizeof(tmp)); } } } sortWholeTree(root); Print(root); cout<<endl; } }
#include <cstdio> #include <string> #include <iostream> #include <vector> #include <algorithm> using namespace std; const int MAXN=50010; struct Node { string data; vector<int> child; }node[MAXN]; int index=0; int newNode(string str) { node[index].data=str; node[index].child.clear(); return index++; } int findChild(int parent,string str) { vector<int>::iterator it=node[parent].child.begin(); while(it!=node[parent].child.end()&&node[*it].data!=str) it++; if(it==node[parent].child.end()) return -1; else return *it; } int create(int n) { int root=newNode(""); while(n--) { //读入一行路径 string str,word; getline(cin,str); //父母、孩子指针 int parent=root,child; //对读入字符串处理 int pos=0; while(pos<str.length()) { //读入一个目录 word.clear(); while(pos<str.length()&&str[pos]!='\\') word+=str[pos++]; if(pos<str.length()&&str[pos]=='\\') pos++; //查找是否存在孩子 int child=findChild(parent,word); //不存在则创建 if(child==-1) { child=newNode(word); node[parent].child.push_back(child); } //准备下一个目录 parent=child; } } return root; } bool cmp(int a,int b) { return node[a].data<node[b].data; } void DFS(int root,int left) { for(int i=0;i<node[root].child.size();i++) { //将孩子根据名称从小到大排序 sort(node[root].child.begin(),node[root].child.end(),cmp); int child=node[root].child[i]; for(int i=0;i<left;i++) printf(" "); cout<<node[child].data<<endl; DFS(child,left+node[child].data.size()+1); } } int main() { int n; while(scanf("%d",&n),n>0) { getchar(); //创建目录树 int root=create(n); //排序并打印 DFS(root,0); //每一个测试样例的输出紧跟一个空行(不然不能通过) printf("\n"); } return 0; }
//对于一条目录里的不同文件,先输出前面的空格,再输出文件名, //注意目录要排序,以及每个每个测试用例之间有一个空行 #include<bits/stdc++.h> using namespace std; int main() { string str[11]; int i,j,n; while(cin>>n){ if(n==0) break; for(int l=0;l<n;l++) //保存测试用例的所有目录 cin>>str[l]; sort(str,str+n); //把测试用例的目录排序 string stra,strb; //父目录和子目录 for(int l=0;l<n;l++){ //开始打印所有目录 strb=str[l]; int count=0; //记录空格数,对于目录里的每个文件,先输出前面的空格。 //在一个目录里空格数是累加的 for(i=0,j=0;i<stra.size()&&j<strb.size();i++,j++){ //统计子目录和父目录相同的文件, //多一个相同的文件就多一个空格 ,包括 \ if(stra[i]==strb[j]) count++; else break; //出现和父目录中不同的文件,跳出,开始打印子目录 } for(;j<strb.size();j++){ //j是在和父目录不同文件处 for(int k=0;k<count;k++) //打印前面的空格 cout<<" "; while(j<strb.size()&&strb[j]!='\\'){ //文件名多于一个字符的话持续打印 cout<<strb[j++]; count++; //空格数随着文件名长度增加 } count++; //向右缩进一个空格 cout<<endl; //打印下一个文件 } stra=strb; //下一个目录 } cout<<endl; //注意每个测试用例间多一个空行 } }
#!/usr/bin/python #-*- coding:utf-8 -*- #Author: Ben import sys def printDegs(degs): space = 0 for deg in degs: if deg.strip() != '': sys.stdout.write(' '*space) sys.stdout.write(deg+'\n') space += len(deg)+1 def printSecDegs(degs, upDegs): degs = degs.split('\\') upDegs = upDegs.split('\\') ld = len(degs); lu = len(upDegs) lm = min(ld, lu) for i in range(lm): if degs[i] == upDegs[i]: degs[i] = ' '*len(upDegs[i]) else: break printDegs(degs) while True: try: N = input() if N == 0: break data = [] for i in range(N): degs = raw_input() if degs[-1] == '\\': degs = degs[:-1] data.append(degs) data.sort() upDegs = '' for deg in data: printSecDegs(deg, upDegs) upDegs = deg sys.stdout.write('\n') except: break
#include<map> #include<iostream> using namespace std; struct dic { map<string, dic> info; }; void CreatDic(dic& dic1, string s) { string name=""; dic temp; temp.info.clear(); for (size_t i = 0; i < s.size()&&s[i]!='\\'; i++) { name += s[i]; } if (dic1.info.find(name) == dic1.info.end()) dic1.info[name] = temp; if (name != s&&name+"\\"!=s) CreatDic(dic1.info[name], s.substr(name.size()+1)); } void print_dic(dic dictionary,int layer) { for (auto i : dictionary.info) { for (size_t i = 0; i < layer*2; i++) { cout << " "; } cout << i.first<<endl; if(!i.second.info.empty()) print_dic(i.second, layer + 1); } } int main() { int length; string s; while (cin >> length) { dic dictionary; for (size_t i = 0; i < length; i++) { cin >> s; CreatDic(dictionary, s); } print_dic(dictionary, 0); cout<<endl; } }
#include <stdio.h> #include <string.h> int main(){ int n; while(scanf("%d", &n)!=EOF){ if(n==0) break; char p[100][100]; // 存放测试集 int f[100]; // 标记测试路径顺序 for(int i=0; i<n; i++){ // 循环输入测试路径 scanf("%s", p[i]); // 输入一个测试路径数据 f[i]=i; // 标记各测试路径的原始顺序 } // 对测试路径排序(根据每个路径根目录字符大小排序) for(int i=0; i<n-1; i++){ for(int j=i+1; j<n; j++){ int k = 0; while(p[f[i]][k]==p[f[j]][k]) k++; if(p[f[i]][k]>p[f[j]][k]){ int tmp = f[i]; f[i] = f[j]; f[j] = tmp; } } } // 打印测试路径 for(int i=0; i<n; i++){ int num=0; // num表示当前路径输出的初始缩进 for(int j=i-1; j>=0; j--){ // 判断根目录是否在已打印路径中出现过 int k = 0, l=0; // k用于遍历一条路径,l用于统计相同目录数 while(p[f[j]][k]==p[f[i]][k] && p[f[j]][k+1]==p[f[i]][k+1]){ if(p[f[j]][k]!='\\') l++; k++; } if(num<2*l) // 更新初始缩进 num = 2*l; } // 设置起始输出下标 int j; // 起始输出目录下标 if(num!=0){ // 有重复的父目录 j = num; // 起始输出下标=初始缩进 if(p[i][j]=='\0'){ // 除已出现目录外,无目录访问时 printf("%c", p[i][0]); // 需直接输出目录名,无缩进 num=0; } for(int k=0; k<num; k++) // 后续还有路径,则需先打印初始缩进 printf(" "); } else j=0; // 无已出现目录,则从头开始打印 // 循环输出测试路径 while(p[f[i]][j]!='\0'){ if(p[f[i]][j]!='\\'){ printf("%c", p[f[i]][j]); num+=2; // 每输出一个目录,输出下个目录需增加两个右缩进 } else{ if(p[f[i]][j+1]!='\0') printf("\n"); // 每输出完一个目录需换行 for(int k=0; k<num; k++) printf(" "); } j++; } printf("\n"); // 换行进行下一个测试路径输出 if(i+1==n) printf("\n"); // 测试集与测试集之间需空一行 } } return 0; }纯C
#include<stdio.h> #include<string.h> void print(char *str,int index,int level) { if(strlen(str) <= index) return; for(int i = 0;i < 2 * level;i++) { printf(" "); } while(str[index] != '\\' && index < strlen(str)) { printf("%c",str[index++]); } printf("\n"); index++; level++; print(str,index,level); } int main() { int n; char data[10][50]; while(scanf("%d",&n) != EOF && n) { for(int i = 0;i < n;i++) { scanf("%s",&data[i]); } for(int i = 0;i < n - 1;i++) { for(int j = 0;j < n - i - 1;j++) { if(strcmp(data[j],data[j + 1]) > 0) { char temp[50]; strcpy(temp,data[j]); strcpy(data[j],data[j+1]); strcpy(data[j + 1],temp); } } } print(data[0],0,0); int index,level; for(int i = 1;i < n;i++) { index = 0; level = 0; for(int j = 0;j < strlen(data[i]);j++) { if(data[i][j] == '\\') level++; if(data[i][j] > data[i - 1][j]) break; index++; } print(data[i],index,level); } printf("\n"); } return 0; }
#include <iostream> #include <string> #include <algorithm> using namespace std; int main() { int n; string s; while (cin >> n) { if (n == 0)break; auto* arr = new string[n]; for (int i = 0; i < n; ++i) { cin >> s; arr[i] = s; } // 题目的注说了同一级的需要按字母顺序排列,不能乱。 sort(arr, arr + n); for (int i = 0; i < n; ++i) { string space; bool flag = true;// 标记这一串跟上一串前j-1处是否相同 // 处理输入的每一个串(也就是每一条路径) for (int j = 0; j < arr[i].size(); ++j) { //这一串跟上一串的j处是否相等,并且前j-1处是否相等 if (i != 0 && arr[i - 1][j] == arr[i][j] && flag) { //如果是字母 if (arr[i - 1][j] != '\\') { //因为不用输出父目录,所以直接过滤 for (int k = j; arr[i][k] != '\\' && k < arr[i].size(); k++, j++); //上面的for循环退出条件是==\或者是数组越界,所以得--让改575行的for循环++j指向\,并且让他不越界 j--; //不输出父目录,只需要添加空格 space.append(" "); } } else { flag = false;//如果进来了这里,则说明这一串跟上一串前j-1处已经不相同了 //是字母的话,则输出空格并且回车 if (arr[i][j] != '\\') { cout << space; //输出该层目录的名字如例子中的cst for (int k = j; arr[i][k] != '\\' && k < arr[i].size(); k++, j++) { cout << arr[i][k]; } // 输入的式子中,最后一个字符是字母(j==arr[i].size())还是\((j + 1) == arr[i].size())都不需要回车 if (j != arr[i].size() && (j + 1) != arr[i].size()) cout << endl; //同上 j--; } else { space.append(" "); } } } // 如果是多次输入,得换行 if (i == n - 1) cout << endl; cout << endl; } } }
#include <algorithm> #include <ios> #include <iostream> #include <sys/types.h> using namespace std; struct treeNode{ string name; treeNode* leftChild; treeNode* rightChild; treeNode(string s,treeNode* l,treeNode* r){ name=s;leftChild=l;rightChild=r; } }; //按照孩子兄弟表示法把其他树都加到主树上来 void addToMain(treeNode* main,treeNode* root){ while(root->name==main->name){ if(main->leftChild==0){ main->leftChild=root->leftChild;return; } main=main->leftChild; root=root->leftChild; while(main->name!=root->name&&main->rightChild!=0){ main=main->rightChild; } if(main->rightChild==0&&main->name!=root->name){ main->rightChild=root;return; } } } //返回一个同样以空格为根的树; treeNode* buildTree(string s){ treeNode* root=new treeNode(" ",0,0); treeNode* p=root; string temp=""; for(int i=0;i<s.size();i++){ if(s[i]=='\\'){ p->leftChild=new treeNode(temp,0,0); p=p->leftChild; temp=""; continue; } temp+=s[i]; } if(temp!=""){ p->leftChild=new treeNode(temp,0,0); } return root; } //先序遍历,用n记录遍历的层数,方便打印相应的空格 void preOrder(treeNode* root,int n){ if(root!=0){ for(int i=0;i<n;i++){ cout<<" "; } cout<<root->name<<endl; if(root->leftChild!=0){ preOrder(root->leftChild,n+1); } if(root->rightChild!=0){ preOrder(root->rightChild,n); } } } string sarr[10]; int main(){ int n; while(scanf("%d",&n)!=-1){ if(n==0){ break; } for(int i=0;i<n;i++){ cin>>sarr[i]; } //按字母顺序排序 sort(sarr,sarr+n); //建立森林的根节点 treeNode* main=new treeNode(" ",0,0); for(int i=0;i<n;i++){ //每一个字符串建立一课只有左子树的树(链) treeNode* root=buildTree(sarr[i]); //把建立的树加到森林上 addToMain(main,root); } //先序遍历main即可,main->name是预设的空格,所以要从main->leftchild开始 preOrder(main->leftChild,0); cout<<endl; } return 0; }
#include<iostream> #include<cstdio> #include<string> using namespace std; int main(){ string str; int caseNumber; while(scanf("%d",&caseNumber)!=EOF){ if(caseNumber==0){ break; } char blankSpaceNum[caseNumber][10]; string s; getline(cin,str); for(int m=0;m<=caseNumber;m++){ getline(cin,s); str.append("\n"); // 添加换行符 str.append(s); } int row=0; int col=0; for(int i=0;i<str.size();i++){ if(str[i]=='\n'){//字符名称 转义字符 ASCII:空格 '\0' 32;反斜杠 '\\' 92 printf("\n"); row++; col=0; } else if(str[i]=='\\'){ printf("\n"); int n=col; while(n--){ printf(" "); } } else if(str[i]=='0'){ return 0; } else{ blankSpaceNum[row][col]=str[i]; if(row!=0 && blankSpaceNum[row][col]==blankSpaceNum[row-1][col]){ } else{ printf("%c",blankSpaceNum[row][col]); } col++; } } } return 0; }
#include <cstdio> #include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; int main(){ int n; while(scanf("%d", &n) != EOF) { if (n == 0) { break; } vector<string> strs(n); //储存目录 for (int idx = 0; idx < n; ++idx) { cin>>strs[idx]; //获取输入的字符串 if (strs[idx].back() != '\\'){ strs[idx].push_back('\\'); //加入\\以便后续更好处理 } } sort(strs.begin(), strs.end()); //分割字符串 vector<string> strArr[n]; for (int idx = 0; idx < n; ++idx) { string s = strs[idx]; string tmp; for (int i = 0; i <= s.size(); ++i) { if (s[i] != '\\') { tmp.push_back(s[i]); continue; } strArr[idx].push_back(tmp); tmp.clear(); } } //打印输出 for(int idx = 0; idx < n; ++idx) { vector<string> s = strArr[idx]; for(int i = 0; i < s.size(); ++i) { if (idx != 0 && s[i] == strArr[idx-1][i]){ //判断和上一个目录是否在同目录下 continue; } for(int j = 0; j < i; ++j) { printf(" "); } cout << s[i] << endl; } if (idx == n-1){ //最后输出一行 printf("\n"); } } } return 0; }一般来说,是输入一组样例,然后我输出一组结果,结果这题虽然也是一组一组输入样例,但是只要一组输出结果,纯纯有病。