爲了指定文件系統中的某個文件,需要用路徑來定位。在類 Unix 系統(Linux、Max OS X、FreeBSD等)中,路徑由若干部分構成,每個部分是一個目錄或者文件的名字,相鄰兩個部分之間用 / 符號分隔。
有一個特殊的目錄被稱爲根目錄,是整個文件系統形成的這棵樹的根節點,用一個單獨的 / 符號表示。在操作系統中,有當前目錄的概念,表示用戶目前正在工作的目錄。根據出發點可以把路徑分爲兩類:
絕對路徑:以 / 符號開頭,表示從根目錄開始構建的路徑。
相對路徑:不以 / 符號開頭,表示從當前目錄開始構建的路徑。
例如,有一個文件系統的結構如下圖所示。在這個文件系統中,有根目錄 / 和其他普通目錄 d1、d2、d3、d4,以及文件 f1、f2、f3、f1、f4。其中,兩個 f1 是同名文件,但在不同的目錄下。
對於 d4 目錄下的 f1 文件,可以用絕對路徑 /d2/d4/f1 來指定。如果當前目錄是 /d2/d3,這個文件也可以用相對路徑 ../d4/f1 來指定,這裏 .. 表示上一級目錄(注意,根目錄的上一級目錄是它本身)。還有 . 表示本目錄,例如 /d1/./f1 指定的就是 /d1/f1。注意,如果有多個連續的 / 出現,其效果等同於一個 /,例如 /d1///f1 指定的也是 /d1/f1。
本題會給出一些路徑,要求對於每個路徑,給出正規化以後的形式。一個路徑經過正規化操作後,其指定的文件不變,但是會變成一個不包含 . 和 .. 的絕對路徑,且不包含連續多個 / 符號。如果一個路徑以 / 結尾,那麼它代表的一定是一個目錄,正規化操作要去掉結尾的 /。若這個路徑代表根目錄,則正規化操作的結果是 /。若路徑爲空字符串,則正規化操作的結果是當前目錄。
第二行包含一個字符串,表示當前目錄。
以下 P 行,每行包含一個字符串,表示需要進行正規化操作的路徑。
/d2/d3
/d2/d4/f1
../d4/f1
/d1/./f1
/d1///f1
/d1/
///
/d1/../../d2
/d2/d4/f1
/d1/f1
/d1/f1
/d1
/
/d2
文件和目錄的名字只包含大小寫字母、數字和小數點 .、減號 - 以及下劃線 _。
不會有文件或目錄的名字是 . 或 .. ,它們具有題目描述中給出的特殊含義。
輸入的所有路徑每個長度不超過 1000 個字符。
輸入的當前目錄保證是一個經過正規化操作後的路徑。
對於前 30% 的測試用例,需要正規化的路徑的組成部分不包含 . 和 .. 。
對於前 60% 的測試用例,需要正規化的路徑都是絕對路徑。
題解
字符串處理。先記錄下當前目錄並賦給ans數組。接下來讀入路徑,若爲相對路徑(不以/開頭)則清空原數組,否則從當前目錄開始進行操作(注意初始目錄爲/的情況)。。感覺問題在讀題上。。讀懂題意就沒啥難的:
貼出代碼。。用了stringstream感覺挺彆扭的但是用cin又會出錯。。不知道爲啥cin.getline(t,1004.'/')只能讀進去第一個目錄...第二個‘/’以後的他就不讀了。。。查到了再改代碼。。先用stringstream湊合一下。。。
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <sstream>
using namespace std;
int main(int argc, char const *argv[])
{
string now;
string input;
char t[1005];
vector<string> start;
start.clear();
vector<string> ans;
const string stay(".");
const string ret("..");
int T;
cin>>T;
cin.get();
int cnt=0;
cin.get();
getline(cin,input);
stringstream ss(input);
while(ss.getline(t,1004,'/'))
{
start.push_back(t);
cnt++;
}
while(T--)
{
getline(cin,input);
stringstream sin(input);
ans=start;
int first=1;
while(sin.getline(t,1004,'/'))
{
if(strcmp(t,"\0")==0)
{
if(first) ans.clear();
continue;
}
string s(t);
now=s;
if(now==stay)
{
if(first) first=0;
continue;
}
else if(now==ret)
{
if(first) first=0;
if(!ans.empty())
ans.erase(ans.end()-1);
}
else
{
if(first) first=0;
ans.push_back(now);
}
}
cout<<"/";
for(int i=0;i<ans.size();i++)
{
cout<<ans[i];
if(i!=ans.size()-1) cout<<"/";
}
cout<<"\n";
}
return 0;
}