leetcode#71。パスを単純化する

トピックリンク

タイトル説明:

Unixスタイルのファイルの絶対パスを考えると、それを単純化する必要があります。つまり、正規のパスに変換します。

Unixスタイルのファイルシステムでは、ドット(。)は現在のディレクトリ自体を示します。さらに、2つのドット(...)は、ディレクトリが上位レベル(親ディレクトリを指す)に切り替えられることを示します。複雑な相対パスセクションで構成されます。詳細については、Linux / Unixの絶対パスと相対パスを参照してください。

返される正規パスは常にスラッシュ/で始まる必要があり、2つのディレクトリ名の間にはスラッシュ/が1つだけ存在する必要があることに注意してください。最後のディレクトリ名(存在する場合)を/で終わらせることはできません。さらに、正規パスは絶対パスを表す最短の文字列である必要があります。

例1:

入力: "/ home /"
出力: "/ home"
説明:最後のディレクトリー名の後にスラッシュがないことに注意してください。

例2:

入力: "
/ ... / "出力: "/"
説明:ルートは到達可能な最高レベルであるため、ルートディレクトリから1レベル上に移動することはできません。

例3:

入力: "/ home // foo /"
出力: "/ home / foo"
説明:正規パスでは、複数の連続するスラッシュを1つのスラッシュに置き換える必要があります。

例4:

入力: "
/ a /./ b / / / c / "出力: "/ c"

例5:

入力: "
/ a / / / b / / c //.//"出力: "/ c"

例6:

入力: "/ a // bc / d //。/。// ..."
出力: "/ a / b / c"


問題解決のアイデア

  この質問の難しさは、質問を辛抱強く読み、状況を要約することです(if-else)。最初に、入力パスを前処理する必要があります。JSArrayオブジェクトには、split主に文字列を分割して文字列配列に戻すために使用されるメソッドがあります。ここで/は、文字列配列を入力パスに分割します。入力パスのさまざまな状況について、次の5つの状況を要約しました。

  1. 遭遇した..前のレベルに戻るには、必要性を、ファイル名が、最近入力されたポップアップ表示されます。
  2. 遭遇したときに.変更を加えないでください;
  3. 忘れない""ください。实例3分割//するsplit""文字列が形成され、配列に結合されることはすでに説明しましたそして、それに遭遇したときは、何も変更しないでください。
  4. 残りは入力する必要のあるファイル名です
  5. さらに、によると实例2、最終スタックが空の場合は、を返す必要があります/

  JSでは、Arrayオブジェクトは、提供pop及びpushスタックをシミュレートする方法。ただし、この質問では、スタックの最初から最後までの機能は実際には使用され
  いない""思います分割文字列のスタイル(特に)を理解していない学生の場合は、Chromeブラウザで自分でデバッグできます。 (右クリック-> 检查-> Sources->ブレークポイントのデバッグ)〜


JSバージョン

var simplifyPath = function (path) {
    
    
    let stack = [];
    const str = path.split("/");

    for (let i = 0; i < str.length; i++) {
    
    
        if (str[i] === ".."){
    
    
            if(stack.length != 0 ){
    
    
                stack.pop();  
            }      
        }              
        else if (str[i] === "" || str[i] === "."){
    
    
            continue;   
        }            
        else{
    
    
            stack.push(str[i]); 
        }
                    
    }

    if (stack.length == 0) {
    
    
        return "/";
    }

    let result = "";
    for (let i = 0; i < stack.length; i++) {
    
    
        result += "/" + stack[i];
    }

    return result;
};

C ++について

  C ++splitは同様の既製の関数がないので、どうすればよいですか?現時点では、getline()機能を検討することができます。その操作に関して、Baiduはこの質問でのその役割についてのみ話します。getline同等splitforするため、組み合わせループgetline(ss, record, '/')、解釈入力文字列ストリームがさss遭遇'/'カットにし、その後record、入力ストリームが有効でなくなるまで(すなわち、文字列全体が完了割る)、入力情報ストリームを記憶します。さらに、ストリームの入出力操作を実行するにssは、入力ストリームのタイプが必要stringsreamです。なお、結果を格納するためのデータ構造は不要stackvector<string>あり、記事全体でファーストインラストアウト機能を使用していないため、それを使用して結果を実現でき、実行時間は4msです。


CPP

class Solution {
    
    
public:
    string simplifyPath(string path) {
    
    
        stringstream ss(path);
        vector<string> records;
        string record = "";

        while(getline(ss, record, '/')){
    
    
            if(record == ".."){
    
    
                if(records.size() != 0){
    
    
                    records.pop_back();
                }
            }
            else if(record == "." || record == ""){
    
    
                continue;
            }
            else{
    
    
                records.push_back(record);
            }
        }

        if(records.size() == 0)
            return "/";

        string result;
        for(auto rec : records)
            result += "/" + rec;

        return result;

    }
};

間違いや厳しくない場合は訂正してください、ありがとうございます。
私のブログ:http//breadhunter.gitee.io

おすすめ

転載: blog.csdn.net/weixin_40807714/article/details/104935917