
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