試題編號: | 201604-3 |
試題名稱: | 路徑解析 |
時間限制: | 1.0s |
內存限制: | 256.0MB |
問題描述: | 問題描述 在操作系統中,數據通常以文件的形式存儲在文件系統中。文件系統一般採用層次化的組織形式,由目錄(或者文件夾)和文件構成,形成一棵樹的形狀。文件有內容,用於存儲數據。目錄是容器,可包含文件或其他目錄。同一個目錄下的所有文件和目錄的名字各不相同,不同目錄下可以有名字相同的文件或目錄。 爲了指定文件系統中的某個文件,需要用路徑來定位。在類 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,表示需要進行正規化操作的路徑個數。 第二行包含一個字符串,表示當前目錄。 以下 P 行,每行包含一個字符串,表示需要進行正規化操作的路徑。 輸出格式 共 P 行,每行一個字符串,表示經過正規化操作後的路徑,順序與輸入對應。 樣例輸入 7 /d2/d3 /d2/d4/f1 ../d4/f1 /d1/./f1 /d1///f1 /d1/ /// /d1/../../d2 樣例輸出 /d2/d4/f1 /d2/d4/f1 /d1/f1 /d1/f1 /d1 / /d2 評測用例規模與約定 1 ≤ P ≤ 10。 文件和目錄的名字只包含大小寫字母、數字和小數點 .、減號 - 以及下劃線 _。 不會有文件或目錄的名字是 . 或 .. ,它們具有題目描述中給出的特殊含義。 輸入的所有路徑每個長度不超過 1000 個字符。 輸入的當前目錄保證是一個經過正規化操作後的路徑。 對於前 30% 的測試用例,需要正規化的路徑的組成部分不包含 . 和 .. 。 對於前 60% 的測試用例,需要正規化的路徑都是絕對路徑。 |
#include<iostream>
using namespace std;
const int N=1001;
#include<string>
string data[N];
string now;
void solve(string* value){
//去掉‘//’
int pos;
while((pos=value->find("//"))!=string::npos)
{
value->erase(pos,1);
}
//去掉‘/./’
while((pos=value->find("/./"))!=string::npos)
value->erase(pos,2);
//去掉 最後一個/
int temp=value->length();
if(temp>1){
if(value->find_last_of("/")==temp-1)
value->erase(temp-1,1);
}
// cout<<"最後的結果是:"<<*value<<endl;
}
string last(string value){
//處理 ../
if(value=="") return value=now;
if(value[0]!='/')
value=now+"/"+value;
int pos=0;
while((pos=value.find("/../"))!=string::npos){
if(pos==0)
value.erase(pos,3);
else {
int lastPos=value.rfind("/",pos-1);
value.erase(lastPos,pos-lastPos+3);
}
// cout<<"此時的value:"<<value<<endl;
// if(value.size()==0) value="/";
}
return value;
}
int main(){
/* string a="/p/./a/./b/c//////d";
solve(&a);
*/
int p;
cin>>p>>now;
//輸入每一行字符串
getchar();
char temp;
//輸入待處理的數據
for(int i=0;i<p;++i){
while((temp=cin.get())!='\n')
data[i]+=temp;
solve(&data[i]);
cout<<last(data[i])<<endl;
}
}