1. 程式人生 > >【LeetCode】71. Simplify Path(C++)

【LeetCode】71. Simplify Path(C++)

地址:https://leetcode.com/problems/simplify-path/

題目:

Given an absolute path for a file (Unix-style), simplify it.

For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
path = "/a/../../b/../c//.//", => "/c"
path = "/a//b////c/d//././/..", => "/a/b/c"

In a UNIX-style file system, a period (’.’) refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("…") moves up a directory, so it cancels out whatever the last directory was. For more information, look here:

https://en.wikipedia.org/wiki/Path_(computing)#Unix_style
Corner Cases:

  • Did you consider the case where path = "/../"?
    In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo"
    .

理解:

按規則往下讀就可以了。可以把每次讀出來的資料夾記錄下來,如果有..且記錄不為空,則把最後的彈出來即可。

實現1:

下面是我最開始的實現,這種實現在遇到"/..."這種輸入的時候有問題,我的寫法讀了兩個…並忽略了下一個,並沒有想到會有這種輸入。。

class Solution {
public:
	string simplifyPath(string path) {
		vector<string> paths;
		size_t len = path.length();
		size_t curr = 0;
		while (curr < len) {
			if (path[curr] == '/') {
				++curr;
				continue;
			}
			else if (path[curr] == '.') {
				++curr;
				if (curr< len&&path[curr] == '.') {
					++curr;
					if (paths.empty())
						continue;
					paths.pop_back();
				}
			}
			else {
				string tmp;
				while (curr < len&&path[curr] != '/'&&path[curr] != '.') {
					tmp += path[curr];
					++curr;
				}
				paths.push_back(tmp);
			}
		}
		string res;
		if(paths.empty())
			res="/";
		else {
			for (auto s : paths)
				res = res + "/" + s;
		}
		return res;
	}
};

優化一下

class Solution {
public:
	string simplifyPath(string path) {
		vector<string> paths;
		size_t len = path.length();
		size_t curr = 0;
		while (curr < len) {
			while (curr < len&&path[curr] == '/')
				++curr;
			if (curr == len) break;
			int j = curr;
			while (j < len&&path[j] != '/')
				++j;
			string tmp = path.substr(curr, j - curr);
			curr = j;
			if (tmp == "..") {
				if (!paths.empty())
					paths.pop_back();
			}	
			else if(tmp!=".")
				paths.push_back(tmp);
		}
		string res;
		if (paths.empty())
			res = "/";
		else {
			for (auto s : paths)
				res = res + "/" + s;
		}
		return res;
	}
};

實現2:

這種實現利用了getline,漲姿勢了,原來還能這麼用。不過好慢啊。

class Solution {
public:
	string simplifyPath(string path) {
		vector<string> paths;
		string tmp;
		istringstream  in(path);
		while (getline(in, tmp, '/')) {
			if (tmp == "" || tmp == ".") continue;
			if (tmp == "..") {
				if (!paths.empty()) paths.pop_back();
			}
			else
				paths.push_back(tmp);
		}
		string res;
		if(paths.empty())
			res="/";
		else {
			for (auto s : paths)
				res = res + "/" + s;
		}
		return res;
	}
};