1. 程式人生 > >CSP考試 2016年04月第3題 路徑解析 C++實現

CSP考試 2016年04月第3題 路徑解析 C++實現

//. 表示本目錄,例如 /d1/./f1 指定的就是 /d1/f1 
//如果有多個連續的 / 出現,其效果等同於一個 /
//絕對路徑:以 / 符號開頭,表示從根目錄開始構建的路徑。
//相對路徑:不以 / 符號開頭,表示從當前目錄開始構建的路徑。
//.. 表示上一級目錄。 . 表示本目錄
#include <iostream> 
#include <string>
//#include <cstring>
//假設當前目錄是標準的 
//考慮所有字串 
//70分 修改版 
//若路徑為空字串,則正規化操作的結果是當前目錄。
//80分 修改版 
//.. 表示上一級目錄
// . 表示本目錄
//對於前 60% 的測試用例,需要正規化的路徑都是絕對路徑。
//輸入../..
//輸出/d2/..
//修改版 使用棧 + substr repace 
//90分 執行錯誤 
// 1
// /d2/d3
// /../...
// /..  
using namespace std;
int main()
{
	int NUM;
	cin>>NUM;
	string a[NUM];
	string b;//輸入的當前目錄保證是一個經過正規化操作後的路徑。
	cin>>b;
	string dj;
	getline(cin,dj);
	int i;
	for(i=0;i<NUM;i++)
	{
		//cin>>a[i];
		getline(cin,a[i]);
	}
	//string c[NUM];
	int m;
	for(m=0;m<NUM;m++)
	{
		//實驗第1個字串 
		//允許出錯
		//絕對路徑:以 / 符號開頭,表示從根目錄開始構建的路徑。
		//相對路徑:不以 / 符號開頭,表示從當前目錄開始構建的路徑。
		//當前目錄能為空嗎
		if(b=="") 
		{
			b="/";
		}
		if(a[m]=="")
		{
			a[m]=b;//若路徑為空字串,則正規化操作的結果是當前目錄
			//continue;
		}
		if(a[m][0]!='/') 
		{
			a[m]=b+'/'+a[m];
		}
		//cout<<a[m]<<endl;
		int j=0;
		for(i=0;i<a[m].size();i++)//去掉多餘的'/' 
		{
			if(a[m][i]!='/')
			{
				a[m][j]=a[m][i];
				j++;
			}else if((a[m][i]=='/')&&(a[m][i+1]!='/'))
			{
				a[m][j]=a[m][i];
				j++;
			}
		}
		for(i=j;i<a[m].size();i++)
		{
			a[m][i]=0;
		}
		//正規化操作要去掉結尾的 /
		if(a[m][a[m].size()-1]=='/')
		{
			a[m][a[m].size()-1]=0;
		}
    	//cout<<a[m]<<endl;
    	//. 表示本目錄
   	 	//將"/./"用"/"替代
   	 	// 1
   	 	// /
   	 	// .
   	 	// /. 解決
		//也許還有問題 
		//當前目錄能為空嗎 
   		 j=0;
		for(i=0;i<a[m].size();i++)
		{
			if((a[m][i]=='/')&&(a[m][i+1]=='.')&&((a[m][i+2]=='/')||(a[m][i+2]=='\0')))// "/./" "/."
			{
				//a[0][j]=a[0][i];
				//j++;
				i=i+1;
			}else 
			{
				a[m][j]=a[m][i];
				j++;
			} 
		} 
		for(i=j;i<a[m].size();i++)
		{
			a[m][i]=0;
		}
		if(a[m][0]=='\0')
   	 	{
   	 		a[m][0]='/';
		}
		//cout<<a[m]<<endl;
		//處理"/../"  90分 執行錯誤 
		// 1
		// /d2/d3
		// ../../../d4/../..
		//執行錯誤 解決 
		// 1
		// /
		// ..
		// /..  解決 
		// .. 表示上一級目錄
		// 90分 錯誤 
		//cout<<a[m]<<endl;
		int zhan[1000];
		for(i=0;i<1000;i++)
		{
			zhan[i]=0;
		}
		//memset(zhan,0,sizeof(zhan));
		int top=-1;
		for(i=0;i<a[m].size();i++)
		{
			//cout<<"top "<<top<<endl;
			if((a[m][i]=='/')&&(a[m][i+1]=='.')&&(a[m][i+2]=='.')&&((a[m][i+3]=='/')))//"/../"
			{
				//cout<<"hi 1"<<endl;
				if(top==-1)
				{
					//cout<<"hello 1"<<endl;
					a[m]=a[m].replace(i,3,"");
					i=i-1;
					continue;
				}
				//出棧 
				int pos;
				pos=zhan[top];
				if(top>-1)
				{
					top--;
				}
				//string str="";
				a[m]=a[m].replace(pos+1,(i-pos+3),"");
				//cout<<a[m]<<endl;
				i=pos-1;
			}else if((a[m][i]=='/')&&(a[m][i+1]=='.')&&(a[m][i+2]=='.')&&(a[m][i+3]=='\0'))//"/.."  
			{
				//cout<<"hi 2"<<endl;
				if(top==-1)
				{
					//cout<<"hello 2"<<endl;
					a[m]="/";
					break;
				}
				//出棧 
				int pos;
				pos=zhan[top];
				if(top>-1)
				{
					top--;
				}	
				//string str="";
				a[m]=a[m].replace(pos+1,(i-pos+2),"");
				//cout<<a[m]<<endl;
				i=pos-1;
			}else 
			{
				if(a[m][i]=='/')
				{
					//入棧
					top++;
					zhan[top]=i; 
				}
			}
			//cout<<a[m]<<endl;
		}
	}
	for(m=0;m<NUM;m++)
	{
		cout<<a[m]<<endl;
	}
	/* 
	cout<<NUM<<endl;
	cout<<b<<endl;
	for(i=0;i<NUM;i++)
	{
		cout<<a[i]<<endl;
	}*/
	return 0;
}
//輸入""
//輸出/d2/d3 

//輸入../..
//輸出/

//輸入../../../
//輸出/