【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;
	}
};

猜你喜欢

转载自blog.csdn.net/Ethan95/article/details/84818180