题目描述:
题目链接:mkdir__牛客网
工作中,每当要部署一台新机器的时候,就意味着有一堆目录需要创建。例如要创建目录“/usr/local/bin”,就需要此次创建“/usr”、“/usr/local”以及“/usr/local/bin”。好在,Linux下mkdir提供了强大的“-p”选项,只要一条命令“mkdir -p /usr/local/bin”就能自动创建需要的上级目录。
现在给你一些需要创建的文件夹目录,请你帮忙生成相应的“mkdir -p”命令。
输入描述:
输入包含多组数据。 每组数据第一行为一个正整数n(1≤n≤1024)。 紧接着n行,每行包含一个待创建的目录名,目录名仅由数字和字母组成,长度不超过200个字符。
输出描述:
对应每一组数据,输出相应的、按照字典顺序排序的“mkdir -p”命令。 每组数据之后输出一个空行作为分隔。
示例
输入
3 /a /a/b /a/b/c 3 /usr/local/bin /usr/bin /usr/local/share/bin输出
mkdir -p /a/b/c mkdir -p /usr/bin mkdir -p /usr/local/bin mkdir -p /usr/local/share/bin
题目理解:
题目读完感觉有点复杂,好像要让我们实现这个命令,还要排序,有的目录被之前包含还不能被输出。 反正读完就一个字 懵! 但其实我们再好好读,或者先看看示例,从第一组数据可以看到如果一个字符串被另一个字符串包含,那么它就不用输出。 再看第二个第二组数据,如果不能完全包含,那排序下输出就好了,只是在输出的时候加上 mkdir -p 字符串就好了。
思路讲解:
有了上面的题目理解,我们对这个题,应该就不担心了。 解决思路就是,首先对每组数据进行排序,排序后长度相近的在一起,如果是 第一组数据那种,排序后,也会相邻,就可以进行筛选了。 然后就比对相邻的字符串,如果上一个比下一个字符串短,那就看是否包含,如果包含那就把它删除。如果不包含就不管它,最后把字符串数组加上前缀输出就好了,还有要注意,每组数据后空一行,这个忘了,怎么做都是错的。 关于目录包含,要避坑,/a 和 /a/b ,前一个是包含在后一个字符串里面的, 但对于 /a 和 /ab/b ,前一个从字符串角度是包含在后一个里面的, 但从目录结构角度是不包含的,所以这种情况要排除。
要说明一个事情,就是从数组中删除一个元素其实还是挺麻烦的,要移动后面元素,就需要 O(n^ 2)的时间复杂度,所以我们采用 伪删除法,就是用一个标记数组,标记要删除的元素。
代码注释:
// write your code here
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(scan.hasNextInt()){
int n= scan.nextInt();
String[] arr = new String[n];
for(int i=0;i< n;i++){
arr[i] = scan.next();
}
Arrays.sort(arr);
// 设一个标记数组
boolean[] flag = new boolean[n];
for(int i=0;i< n-1;i++){
// 如果前一个字符串小于后一个字符串,并且包含在后一个字符串,并且是作为一级目录包含在
// 其中,那就给它标记。
if(arr[i].length()< arr[i+1].length() &&
arr[i+1].contains(arr[i]) &&
arr[i+1].charAt(arr[i].length())=='/'){
flag[i] =true;
}
}
// 最后循环遍历,只输出没有被特殊标记的字符串
for(int i=0;i< n;i++){
if(!flag[i]){
System.out.println("mkdir -p "+arr[i]);
}
}
System.out.println();
}
}
}