题目: 手写一个方法,可以简化绝对路径。
比如
输入 "/home/", 得到 "/home"
输入 "/a/./b/../../c/", 得到 "/c"
输入 "/./a//b", 得到 "/a/b"
思路
虽然是Java写的,但是我还是尽量避免使用Java自带的方法。只使用了原始类型char.
自己手写了一个Bag类来记录每一级的文件名。这个Bag类只有一个add方法。然后又写了一个Stack类来存各级的Bag,可以push和pop;内部实现都是一个char数组。
这道题里主要需要解决的问题有:
- 普通输入: /a/b/c
- 多余的斜杠要忽略: /a/b/, /a//b
- 一个点表示留在当前路径: /a/./b => /a/b
- 两个点表示退回上一级路径: /a/../b => /b
这里面我的解决办法是
用自己设定的状态码来记录每一次碰到的符号。
int MEET_SLASH = 100;
int MEET_DOT = 200;
int MEET_CONTENT = 300;
int BEGIN = 0;
这样每次循环到新的字符的时候,都能通过上一次的状态来判断应该做些什么。
比如:之前是MEET_DOT,那这次如果还是遇到DOT的的话,就把stack pop了。
具体的逻辑看代码即可。
这里也只考虑了有效的输入。
/**
* Created by creat on 2018/7/26.
* Given an absolute path for a file (Unix-style), simplify it.
* For example,
* path = "/home/", => "/home"
* path = "/a/./b/../../c/", => "/c"
*/
public class SimplifyPath {
int MEET_SLASH = 100;
int MEET_DOT = 200;
int MEET_CONTENT = 300;
int BEGIN = 0;
private class Bag {
int position = -1;
char[] content = new char[100];
void add(char c) {
content[++position] = c;
}
int size() {
return position + 1;
}
public String toString() {
String toRet = "";
for (int i = 0; i < size(); i++) {
toRet += content[i];
}
return toRet;
}
}
private class Stack {
int position = -1;
Bag[] content = new Bag[100];
void push(Bag bag) {
if (isFull()) {
System.out.println("max input reached");
return;
}
content[++position] = bag;
}
Bag pop() {
if (isEmpty()) {
System.out.println("Invalid Input");
return null;
}
return content[position--];
}
int size() {
return position + 1;
}
boolean isEmpty() {
return position == -1;
}
boolean isFull() {
return position == 99;
}
void print() {
for (int i = 0; i < size(); i++) {
System.out.print("/" + content[i]);
}
System.out.println();
}
}
private Stack simplifyPath(String path) {
char[] input = path.toCharArray();
int status = BEGIN;
Stack pathStack = new Stack();
Bag bag = new Bag();
for (int i = 0; i < input.length; i++) {
if (input[i] == '/') {
if (status == MEET_CONTENT) {
pathStack.push(bag);
bag = new Bag();
}
status = MEET_SLASH;
continue;
}
if (input[i] != '/' && input[i] != '.') {
if (status == MEET_SLASH || status == MEET_CONTENT) {
bag.add(input[i]);
}
if (i == input.length - 1) {
pathStack.push(bag);
}
status = MEET_CONTENT;
continue;
}
if (input[i] == '.') {
if (status == MEET_DOT) {
pathStack.pop();
}
status = MEET_DOT;
continue;
}
}
pathStack.print();
return pathStack;
}
public static void main(String[] args) {
SimplifyPath sp = new SimplifyPath();
sp.simplifyPath("/././abc"); // prints /abc
sp.simplifyPath("/./a/b"); // prints /a/b
sp.simplifyPath("/a/../b"); // prints /b
sp.simplifyPath("//a//b/"); // prints /a/b
sp.simplifyPath("/a/./b/../../c/"); // prints /c
sp.simplifyPath("/home/"); // prints /home
}
}