列表

详情


SH9. Unix路径简化

描述

简化 Unix 风格的路径,需要考虑的包括 "/../", "//", "/./" 等情况

输入描述

Unix 风格的路径

输出描述

简化后的Unix 风格路径

示例1

输入:

/a/./b/../../c/

输出:

/c

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 364KB, 提交时间: 2021-07-19

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define not !

typedef enum { OK = 1, ERROR = -1, MEMORY_OVERFLOW = -2 } Status;

// ====================== 链式栈存储结构的表示与实现 ====================
typedef char* SElemType;

typedef struct StackNode {
  SElemType data;         /* 链式栈节点的数据域 */ 
  struct StackNode* next; /* 链式栈节点的指针域 */
} StackNode;

typedef struct {
  StackNode* top;
  size_t length;
} LinkStack;

Status InitStack(LinkStack* S) {
  (*S).top = NULL;
  (*S).length = 0;
  return OK;
}

int StackEmpty(LinkStack* S) {
  return (*S).length == 0;
}

size_t StackLength(LinkStack* S) {
  return (*S).length;
}

Status Push(LinkStack* S, SElemType e) {
  StackNode* new_node = (StackNode*) malloc(sizeof(StackNode));
  if (!new_node) {
    fprintf(stderr, "Push Memory Overflow: %s\n", strerror(errno));
    return ERROR;
  }
  
  (*new_node).data = e;
  (*new_node).next = (*S).top;
  (*S).top = new_node;
  ++(*S).length;
  return OK;
}

Status Pop(LinkStack* S, SElemType* e) {
  if (StackEmpty(S)) {
    fprintf(stderr, "Pop ERROR: The stack is empty!\n");
    return ERROR;
  }
  
  StackNode* p = (*S).top;
  *e = (*p).data;
  (*S).top = (*p).next;
  
  free(p);
  --(*S).length;
  return OK;
}

Status DestroyStack(LinkStack* S) {
  return OK;
}

// ====================== 链式栈存储结构的表示与实现 ====================

void reverse(char* strs[], const int n) {
  int l = -1, r = n;
  while (++l < --r) {
    char* tmp = *(strs + l);
    *(strs + l) = *(strs + r);
    *(strs + r) = tmp;
  }
}

const char* const DELIM = "//";

int main(const int argc, const char* argv[]) {
  
  char input[1024] = "";
  gets(input);
  
  LinkStack S;
  InitStack(&S);
  
  char *ch, *tok = strtok(input, DELIM);
  while (tok) {
    if (strcmp(tok, ".") == 0) {
      ; // NOP == no operation == do nothing == 空操作
    } else if (strcmp(tok, "..") == 0) {
      if (not StackEmpty(&S)) Pop(&S, &ch);
    } else {
      Push(&S, tok);
    }
    tok = strtok(NULL, DELIM);
  }
  
  char* strs[1024]; 
  int i, n = 0;
  while (not StackEmpty(&S))
    Pop(&S, strs + n++);
  
  reverse(strs, n);
  putc('/', stdout);
  for (i = 0; i < n; ++i) {
    fputs(*(strs + i), stdout);
    if (i < n - 1) putc('/', stdout);
  }
  
  return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-11-01

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    vector<string> dir; //用vector代替栈 因为index好找
    int len=s.size();
    int i,j;
    string tmp;
    for(i=0;i<len;i++)
    {
        if(s[i]=='/')
        {
            j=i+1;
            while(j<len && s[j]!='/')
                j++;
            if(i+1<len)
            {
                tmp=s.substr(i+1,j-i-1);// 两个/之间的子串
                if(tmp=="..")
                {
                    if(!dir.empty())
                        dir.pop_back();
                }
                else if(tmp=="." ||tmp.empty())
                {}
                else if(!tmp.empty())
                    dir.push_back(tmp);
            }
        }
    }
    if(dir.empty())
        cout<<"/";
    else
    {
        for(int i=0;i<dir.size();i++)
            cout<<"/"<<dir[i];
    }
    cout<<endl;
    return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-10-31

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    vector<string> dir; //用vector代替栈 因为index好找
    int len=s.size();
    int i,j;
    string tmp;
    for(i=0;i<len;i++)
    {
        if(s[i]=='/')
        {
            j=i+1;
            while(j<len && s[j]!='/')
                j++;
            if(i+1<len)
            {
                tmp=s.substr(i+1,j-i-1);// 两个/之间的子串
                if(tmp=="..")
                {
                    if(!dir.empty())
                        dir.pop_back();
                }
                else if(tmp=="." ||tmp.empty())
                {}
                else if(!tmp.empty())
                    dir.push_back(tmp);
            }
        }
    }
    if(dir.empty())
        cout<<"/";
    else
    {
        for(int i=0;i<dir.size();i++)
            cout<<"/"<<dir[i];
    }
    cout<<endl;
    return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 392KB, 提交时间: 2020-08-13

#include <iostream>
#include <string>
#include <sstream>
#include <vector>

using namespace std;

int main(){
    string s;
    cin >> s;
    vector<string> sta;
    string buf;
    istringstream ins(s);
    while(getline(ins, buf, '/')){
        if(!buf.empty() && buf != "." && buf != ".."){
            sta.push_back(buf);
        }
        else{
            if(!sta.empty() && buf == ".."){
                sta.pop_back();
            }
        }
    }
    if(sta.empty()){
        cout << "/";
        return 0;
    }
    string res;
    for(string& s : sta){
        res += "/" + s;
    }
    cout << res;
    return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 400KB, 提交时间: 2020-09-08

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    vector<string> dir; //用vector代替栈 因为index好找
    int len=s.size();
    int i,j;
    string tmp;
    for(i=0;i<len;i++)
    {
        if(s[i]=='/')
        {
            j=i+1;
            while(j<len && s[j]!='/')
                j++;
            if(i+1<len)
            {
                tmp=s.substr(i+1,j-i-1);// 两个/之间的子串
                if(tmp=="..")
                {
                    if(!dir.empty())
                        dir.pop_back();
                }
                else if(tmp=="." ||tmp.empty())
                {}
                else if(!tmp.empty())
                    dir.push_back(tmp);
            }
        }
    }
    if(dir.empty())
        cout<<"/";
    else
    {
        for(int i=0;i<dir.size();i++)
            cout<<"/"<<dir[i];
    }
    cout<<endl;
    return 0;
}

上一题