一、题意
1.简述
2.样例
Input
7
/d2/d3
/d2/d4/f1
…/d4/f1
/d1/./f1
/d1///f1
/d1/
///
/d1/…/…/d2
Output
/d2/d4/f1
/d2/d4/f1
/d1/f1
/d1/f1
/d1
/
/d2
Hint
二、算法
主要思路
是一道中级模拟题。思路比较简单,处理字符串较为复杂,如果对于处理字符串的方法很熟悉,这道题应该比较好通过。
思路:利用栈。对于绝对路径,路径栈一开始是空的。对于相对路径,路径栈在一开始则要按顺序压入当前路径中的各个目录。然后以
/
/
/为分隔符对待正规化的路径进行切分,遇到
“
.
.
”
“..”
“..”则
p
o
p
pop
pop栈顶元素,遇到
"
.
"
"."
"."或者空(说明是这种情况:
"
/
/
/
/
"
""
"////"),则不作任何操作;其他的则直接压入栈。
注意两种边界情况:待正规化的路径为
"
/
"
"/"
"/"或者空行,特殊处理即可。
字符串处理方面的技巧
该题可以参考博客:
代码超短的解法
主要要充分利用stringstream
和getline
。
getline
能够处理空行,也就是如果遇到空行,则直接返回一个空串(换句话说也就是结束一次读入),如果是cin
,遇到空行不会结束,直到遇到一个能够读的字符,也就是说如果是连续多个\n
,cin
一并忽略,直到遇到不是\n
的字符。所以其处理不了空行。
用cin
遇到换行则停止读入。但是,这个换行还能通过getchar()
读进来。所以如果cin
和getline
一块使用的话,需要注意将cin
残留的换行读掉,否则如果后面是getline
,则读出来是个空串。
三、代码
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <sstream>
#include <stack>
using namespace std;
string curMenu[1010];
int cmidx = 0;
void output(stack<string>& stk){
if(stk.empty()) return;
string topstr = stk.top();
stk.pop();
output(stk);
cout<<'/'<<topstr;
}
void clearStream(ostringstream& stream){ //既要清空状态也要清空内容
stream.clear();
stream.str("");//清空内容
}
int main() {
int p;
cin>>p;
getchar(); //处理空行
string str[12];
getline(cin,str[0],'\n');
//cin>>str[0]; //当前目录
const char *sp0 = str[0].c_str();
//预处理当前目录
ostringstream stream;
for (int i = 1; i < str[0].length(); ++i) {
if(sp0[i]!='/'){
stream<<sp0[i];
} else{
curMenu[cmidx++] = stream.str();
clearStream(stream);
}
}
if (!stream.str().empty())
curMenu[cmidx++] = stream.str();
//处理p个目录
for (int i = 1; i <= p; ++i) {
stack<string> stk;
int isj = 1; //是否是绝对路径
getline(cin,str[i],'\n');
if (str[i].empty()){ //空行
for (int j = 0; j < cmidx; ++j) {
stk.push(curMenu[j]);
}
//输出
if (stk.empty()) cout<<'/';
output(stk);
cout<<endl;
continue;
}
int lth = str[i].length();
const char *sp = str[i].c_str();
if (sp[0]!='/'){ //相对路径
isj = 0;
for (int j = 0; j < cmidx; ++j) {
stk.push(curMenu[j]);
}
}
clearStream(stream);
bool isok = 0; //是否可以压栈
for (int j = isj; j < lth; ++j) {
string temp;
if (j == lth-1){
isok = 1;
if (sp[j] != '/')
stream<<sp[j];
temp = stream.str();
}
else if(sp[j]!='/'){
stream<<sp[j];
isok = 0;
}
else{ //不是最后一个但是‘/’
temp = stream.str();
isok = 1;
clearStream(stream);
}
//压栈
if(!isok) continue;
if (temp==".."){
if(!stk.empty())
stk.pop();
} else if (!temp.empty() && temp!="."){
stk.push(temp);
}
}
//输出
if (stk.empty()) cout<<'/'; //如果只有一个/
output(stk);
cout<<endl;
}
return 0;
}
/*
7
/d2/d3
/d2/d4/f1
../d4/f1
/d1/./f1
/d1///f1
/d1/
///
/d1/../../d2
*/