CCF201604-3路徑解析C++未完善源碼

問題描述
  在操作系統中,數據通常以文件的形式存儲在文件系統中。文件系統一般採用層次化的組織形式,由目錄(或者文件夾)和文件構成,形成一棵樹的形狀。文件有內容,用於存儲數據。目錄是容器,可包含文件或其他目錄。同一個目錄下的所有文件和目錄的名字各不相同,不同目錄下可以有名字相同的文件或目錄。
  爲了指定文件系統中的某個文件,需要用路徑來定位。在類 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% 的測試用例,需要正規化的路徑都是絕對路徑。

唉,當前測試成績20分,打臉,真的沒有心思去思考到底哪裏出錯了,歡迎指正。
一下是我的源碼:

include

include

include

using namespace std;
string currentPath;//當前路徑

//判斷輸入合法性
bool isCorrect(string str)
{
for (int i = 0; i < str.size();i++)
{
if (!((str[i]>’A’&&str[i]<’Z’) || (str[i]>’a’&&str[i]<’z’) || (str[i]>’0’&&
str[i]<’9’) || (str[i] == ‘.’) || (str[i] == ‘_’) || (str[i]==’-‘)||(str[i]==’/’)))
{
return false;
}
}
return true;
}

void print(vector vec)
{
int i = 0;
for (; i < vec.size();i++)
{
cout << vec[i] << ’ ‘;
}
cout << endl;
}

//將輸入字符串分割爲不包含“/”的子字符串並保存到vector.
void splitString(string &path, vector &vecStr, string &keyStr)
{
vecStr.clear();
string::size_type n1 = 0, n2 = path.find(keyStr);
while (n2 != string::npos)
{
string temp = path.substr(n1, n2 - n1);
if (!temp.empty())
{
vecStr.push_back(temp);
}
n1 = n2+keyStr.size();

    n2 = path.find(keyStr, n1);
}
if (n1 != path.length())
{
    vecStr.push_back(path.substr(n1));
}

}

//參數(當前路徑)一定是絕對路徑,主要作用是去除重複的“/”以及末尾的“/”
string toNormalPath(string currentPath)
{
vector paths;
string ch=”/”,temPath;
splitString(currentPath, paths, ch);
for (int i = 0; i < paths.size();i++)
{
temPath =temPath+ “/” + paths[i];
}
return temPath;
}

//回到上一級目錄,結果可以爲空,空 就表示是根目錄,待到最終結果是在將其替換爲“/”
string toLastDirectary(string path)
{
if (path.empty())
{
return path;
}
string::size_type n1, n2=path.find(“/”);
while (n2!=string::npos)
{
n1 = n2;// /dfg
n2 = path.find(“/”, n1 + 1);
}
string str = path.substr(0, n1);

return str;

}

//總的路徑解析函數,返回最終的正規化路徑。
string solvePath(string path,string keyStr)
{
if (path.empty())
{
return currentPath;
}
vector vecStr;
string temPath;
char ch = ‘/’;
splitString(path, vecStr, keyStr);

if (vecStr.empty())
{
    if (path[0] == '/')
    {
        return "/";
    }
    else
        return currentPath;
}

if (vecStr[0]==".")
{
    temPath = currentPath;
}
else if (vecStr[0] == "..")
{
    temPath = toLastDirectary(currentPath);
}
else
{
    temPath = "/" + vecStr[0];
}

if (vecStr.size()==1)
{
    return temPath.empty() ? "/" : temPath;
}

for (int i = 1; i < vecStr.size();i++)
{
    if (vecStr[i]==".")
    {
        continue;
    }
    else if (vecStr[i]=="..")
    {
        temPath = toLastDirectary(temPath);
    }
    else
    {

        temPath = temPath + "/" + vecStr[i];

    }
}
//因爲空表示之前的根目錄,如果在之前就將根目錄直接用“/”表示的話,
//在上面的temPath = temPath + "/" + vecStr[i];處就會出現雙斜槓(解析圖中回到根目錄時)
return temPath.empty()?"/":temPath;

}

int main()
{
int n;
string temPath;//解析過程的中間變量,前一階段用作輸入臨時變量,後一階段存儲當前解析狀態。
vector paths;
string key = “/”;
cin >> n >> currentPath;
currentPath = toNormalPath(currentPath);//將當前路徑正規化
if (!isCorrect(currentPath)||n<1||n>10)
{
return 0;
}

for (int i = 0; i < n;i++)
{
    cin >> temPath;
    if (!isCorrect(temPath))
    {
        return 0;
    }
    //print(paths);
    paths.push_back(temPath);
}

for (int i = 0; i < paths.size();i++)
{
    temPath = solvePath(paths[i], key);
    //temPath = toNormalPath(temPath);
    cout << temPath << endl;

}
return 0;

}

發佈了38 篇原創文章 · 獲贊 84 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章