1. 程式人生 > >LeetCode算法系列:71. Simplify Path

LeetCode算法系列:71. Simplify Path

目錄

題目描述

演算法實現

題目描述

Given an absolute path for a file (Unix-style), simplify it. 

For example,path = "/home/", => "/home"path = "/a/./b/../../c/", => "/c"path = "/a/../../b/../c//.//", => "/c"path = "/a//b////c/d//././/..", => "/a/b/c"

In a UNIX-style file system, a period ('.') refers to the current directory, so it can be ignored in a simplified path. Additionally, a double period ("..") moves up a directory, so it cancels out whatever the last directory was. For more information, look here: 

https://en.wikipedia.org/wiki/Path_(computing)#Unix_style

Corner Cases:

  • Did you consider the case where path = "/../"? In this case, you should return "/".
  • Another corner case is the path might contain multiple slashes '/' together, such as "/home//foo/". In this case, you should ignore redundant slashes and return "/home/foo"
    .

演算法實現

  • 首先將path按照'/'為間隔分開成字串組
  • 對字串組的每一個元素進行判斷,建立一個新的字串陣列
    • 如果該元素為空("/")或者為點(".")則直接跳過,
    • 如果該元素為雙點("..")則需判斷新字串陣列是否為空,若非空,則將最後一個元素刪除
    • 如果為其他元素,則直接加入新字串組
  • 最後將新字串組的每一個元素前面加'/'並連成一個字串返回,即結果
class Solution {
public:
    //分割字串的函式,將字串沿字元token分開成字串集合
    vector<string> split(string s,char token){
        istringstream iss(s);
        string word;
        vector<string> vs;
        while(getline(iss,word,token)){
            vs.push_back(word);
        }
        return vs;
    }
    string simplifyPath(string path) {
        if(path.empty() || path.length() == 0)return path;
        vector<string> words = split(path,'/');
        vector<string> suanz;
        string res;
        for(auto word:words){            
            if(word == "." || word.length() == 0)continue;
            else if(word == "..")
                //下面這個大括號必須要加,不然下面的else會被誤解為下面的if語句的
            {
                if(!suanz.empty())suanz.pop_back();
            }                
            else{
                suanz.push_back(word);
            }
                
        }
        if(suanz.size() == 0)return "/";
        else
            for(auto word:suanz)
            {
                res += "/";
                res += word;
            } 
        return res;
    }
};

關於字串分割

    vector<string> split(string s,char token){
        istringstream iss(s);
        string word;
        vector<string> vs;
        while(getline(iss,word,token)){
            vs.push_back(word);
        }
        return vs;
    }

這個函式是參考網路上其他博主的,可以將字串沿著字元token的位置分割開。在這個函式中,istringstream 將字串s轉換成了一個數據流,而getline(iss,word,token)則是得到字串的一部分,C++reference的參考如下:

(1)	
istream& getline (istream&  is, string& str, char delim);
istream& getline (istream&& is, string& str, char delim);
(2)	
istream& getline (istream&  is, string& str);
istream& getline (istream&& is, string& str);
  • Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).
  • The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.
  • If the delimiter is found, it is extracted and discarded (i.e. it is not stored and the next input operation will begin after it).
  • Note that any content in str before the call is replaced by the newly extracted sequence.
  • Each extracted character is appended to the string as if its member push_back was called.

其中引數

//Parameters
is
istream object from which characters are extracted.
str
string object where the extracted line is stored.
The contents in the string before the call (if any) are discarded and replaced by the extracted line.

寫了兩個例子如下:

// extract to string
#include <iostream>
#include <string>

int main ()
{
  std::string name;

  std::cout << "Please, enter your full name: ";
  std::getline (std::cin,name,'/');
  std::cout << "Hello, " << name << "!\n";

  return 0;
}

//result
Please, enter your full name: Wang/yi/Fan
Hello, Wang!
// extract to string
#include <iostream>
#include <string>

int main ()
{
  std::string name;

  std::cout << "Please, enter your full name: ";
  std::getline (std::cin,name);
  std::cout << "Hello, " << name << "!\n";

  return 0;
}

//result
Please, enter your full name: Efan
Hello, Efan!