Java资深小白,不足之处,或者有任何错误欢迎指出。 --蓝紫
题目
我们都知道在Linux中使用 …/ 可以帮助我们快速切换到上一级目录。那么如果用字符串 /aa/bb/…/cc 来表示文件路径,按照这样的规则完成回退之后的路径就会变成/aa/cc, 思考如何用编程来快速实现?(读完题可以先给自己点时间思考一下,你的思路是怎么样的)
实现
题目很短,规则简洁,简单思路就是将字符串按 ’ / ’ 进行拆分,获得一个拆分后数组,若遇到 … 就删掉前一个拆分项,最后将结果输入出来。
- 实现思路一:数组
创建一个新的数组来接收结果数据,将拆分后数组从头到尾查询,遇到 … 符号就移动指针,将当前值的下一位的指针数组移动在上一位数据处。这种方式会存在很大的问题,若存在连续多个 …时,会不停的移动和赋值的话,指针无法确定移动的次数和最后的位置,所以数组的方式并不能解决这个问题。 - 实现思路二:栈
稍微转一下思路,当从头到尾去遍历一个数组的时候,移动指针换成进出,满足条件进入,遇到…将上一个进入的数据删掉,这样的进出模式就非常符合进栈和出栈的方式了。
栈的数据结构是按照先进后出的原则存储数据。遍历拆分后数据,当遇到 …需要退回上一位数据的时候,刚好用出栈方法就满足了。所以我们使用栈的进栈方法push()和出栈方法pop()就将这个问题简单解决了。
实现代码如下。
/**
* 根本相对路径找到绝对路径
*
* <pre>
* /aa/bb/../cc ==》/aa/cc
* </pre>
*
* @param url
* @return
*/
public static String getAbtUrlUseStock(String url) {
if (url == null || url.isEmpty()) {
return "转换失败";
}
Stack<String> in = new Stack<>();
String[] arr = url.split("/");
for (int i = 1; i < arr.length; i++) {
String s = arr[i];
if (s.equals("..")) {
if (in.empty()) {
return "转换失败";
}
in.pop();
} else {
in.push(s);
}
}
while (!in.empty()) {
StringBuffer urlNew = new StringBuffer();
for (String s : in) {
urlNew.append("/" + s);
}
return urlNew.toString();
}
return "转换失败";
}
public static void main(String[] args) {
String url = "/aa/../../cc";
String url2 = "/aa/bb/../cc";
String url3 = "/aa/bb/cc/../../../../cc";
String url4 = "/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc/aa/bb/cc/../../../cc";
System.out.println("========结果=======");
System.out.println(getAbtUrlUseStock(url));
System.out.println(getAbtUrlUseStock(url2));
System.out.println(getAbtUrlUseStock(url3));
System.out.println(getAbtUrlUseStock(url4));
}
执行结果:
如果想详细了解栈,可以找相关博客学习一下。参考:【图解数据结构】栈全面总结