Simplify Path
Given an absolute path for a file (Unix-style), simplify it.
For example,
path = "/home/", => "/home"
path = "/a/./b/../../c/", => "/c"
click to show corner cases.
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".
思路解析:
面对字符串题目一定要保持清醒,先分析好题目之后再开始码代码。
题目的要求是输出Unix下的最简路径,Unix文件的根目录为"/","."表示当前目录,".."表示上级目录。
例如:
输入1:
/../a/b/c/./..
输出1:
/a/b
模拟整个过程:
1. "/" 根目录
2. ".." 跳转上级目录,上级目录为空,所以依旧处于 "/"
3. "a" 进入子目录a,目前处于 "/a"
4. "b" 进入子目录b,目前处于 "/a/b"
5. "c" 进入子目录c,目前处于 "/a/b/c"
6. "." 当前目录,不操作,仍处于 "/a/b/c"
7. ".." 返回上级目录,最终为 "/a/b"
实现方法:用一个堆栈来模拟路径的行为,遇到"."不操作,遇到".."退栈,其他情况都压入堆栈。
//vs2012测试代码 #include<iostream> #include<stack> #include<string> using namespace std; class Solution { private: void pathToDirectories( stack<string> &directories , string &path) { string name; name.clear(); path = path + '/'; for(int i=0; i<path.length(); i++) { if( path[i]=='/' ) { if( !name.empty() ) if ( name[0]=='.' && name.length()==1 ) name.clear(); else if( name[0]=='.' && name.length()==2 && name[1]=='.' ) { if( !directories.empty() ) directories.pop(); name.clear(); } else { directories.push(name); name.clear(); } } else name = name + path[i]; } } void directoriesToPath( string &ans,stack<string> &directories) { ans.clear(); while( !directories.empty() ) { ans = directories.top() + '/'+ ans ; directories.pop(); } if( !ans.empty() ) ans = ans.substr( 0,ans.length()-1 );//substr 方法:返回一个从指定位置开始,并具有指定长度的子字符串。 ans = '/' + ans; } public: string simplifyPath(string path) { stack<string> directories; pathToDirectories( directories,path ); string ans; directoriesToPath ( ans,directories ); return ans; } }; int main() { string path; getline( cin , path); //或者cin>>s; Solution lin; cout<<lin.simplifyPath(path)<<endl; return 0; }
//方法一:自测Accepted class Solution { private: void pathToDirectories( stack<string> &directories , string &path) { string name; name.clear(); path = path + '/'; for(int i=0; i<path.length(); i++) { if( path[i]=='/' ) { if( !name.empty() ) if ( name[0]=='.' && name.length()==1 ) name.clear(); else if( name[0]=='.' && name.length()==2 && name[1]=='.' ) { if( !directories.empty() ) directories.pop(); name.clear(); } else { directories.push(name); name.clear(); } } else name = name + path[i]; } } void directoriesToPath( string &ans,stack<string> &directories) { ans.clear(); while( !directories.empty() ) { ans = directories.top() + '/'+ ans ; directories.pop(); } if( !ans.empty() ) ans = ans.substr( 0,ans.length()-1 ); ////substr 方法:返回一个从指定位置开始,并具有指定长度的子字符串。 ans = '/' + ans; } public: string simplifyPath(string path) { stack<string> directories; pathToDirectories( directories,path ); string ans; directoriesToPath ( ans,directories ); return ans; } };
原文地址:http://blog.csdn.net/keyyuanxin/article/details/43699497