简化路径为符合unix风格的字符串

题目

给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 '/' 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (..) 表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,'//')都被视为单个斜杠 '/' 。 对于此问题,任何其他格式的点(例如,'...')均被视为文件/目录名称。

请注意,返回的 规范路径 必须遵循下述格式:

始终以斜杠 '/' 开头。
两个目录名之间必须只有一个斜杠 '/' 。
最后一个目录名(如果存在)不能 以 '/' 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 '.' 或 '..')。
返回简化后得到的 规范路径 。

示例 1:
输入:path = "/home/"
输出:"/home"
解释:注意,最后一个目录名后面没有斜杠。
示例 2:
输入:path = "/../"
输出:"/"
解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:
输入:path = "/home//foo/"
输出:"/home/foo"
解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。
示例 4:
输入:path = "/a/./b/../../c/"
输出:"/c"

提示:

1 <= path.length <= 3000
path 由英文字母,数字,'.','/' 或 '_' 组成。
path 是一个有效的 Unix 风格绝对路径。

题目分析

在一个unix风格的路径中,只有三个可能出现的元素:
1.'/';
2.'.';
3.'文件/文件夹名称'
在这个前提下,我们可以注意到,需要重点关注的只有是否需要转入上一级目录以及文件/文件夹的名称。
也就是说 / 和 单独的一个'.'我们是完全不需要进行处理的,因为这两个元素我们既不需要转到上一级目录,也不需要进入下一级目录。
有一个函数能够帮助我们忽略一部分元素,String中的split方法。这个方法可以针对我们指定的某个字符来将字符串分割为字符数组。

String names = path.split('/');

通过这句话,names中只有'.'和'文件/文件夹名称'了。那么我们针对 '..'需要转入上一级目录,这让我们想到可以使用栈的特性将最上面的一层目录弹出以达到跳到上一级目录的目的。
现在我们知道我们需要将目录顺序记录在一个载体里,以便我们最后的输出。同时这个载体需要能满足栈的特性。那么什么样的数据结构能够同时满足尾部弹出和头部弹出?
很容易想到双端队列。这种队列既能够从尾部操作元素,也能从头部操作。
Deque,在JAVA中一个Queue的子类。
如果想要了解更多关于java中queue的信息,可以跳入这个链接
在这里我们只需要用到

pollLast    弹出队尾的元素
offerLast   从队尾插入元素并返回bool值
pollFirst   弹出队首元素

完整代码

    public String simplifyPath(String path) {
        String[] names = path.split("/"); //将path按照/分割为字符串数组
        Deque<String> stack = new ArrayDeque<String>();  //创建元素为String 的双端队列
        for(String name: names){
            if("..".equals(name)){   //..代表需要跳转到上一级目录,对应着出栈
                if(!stack.isEmpty()){
                    stack.pollLast(); 
                }
            }else if(name.length()>0 && !".".equals(name)){
                stack.offerLast(name);      //从队尾插入元素,等同于入栈,判断条件为不为空且不是单个的'.'
            }
        }

        String result = new String();       //这里可以是String也可以是StringBuffer;差别在后面插入新的字符或者字符串的方式不一样;
        if(stack.isEmpty()){
            result = result+'/';  
        }else{
            while(!stack.isEmpty()){
                result = result+'/';
                result = result + stack.pollFirst();
            }
        }

        return result;
    }
posted @ 2024-05-30 22:25  陶醉的碎片  阅读(10)  评论(0编辑  收藏  举报