zoukankan      html  css  js  c++  java
  • 精简Linux文件路径

    精简Linux的文件路径:

    1. ..回退的功能
    2. .留在当前文件夹
    3. //仅仅保留一个/
    4. abc/..要返回.
    5. 报错
    6. 删除最后一个/
    主要思路: 用栈记录路径的起始位置,讨论/后的不同情况就可以:

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <limits.h>
    #include <assert.h>
    #include <stack>
    using namespace std;
    int selectK(int num[], int k, int l, int r) {
      
      assert(k <= (r - l + 1) && k >= 1);
      int mid = (l + r) / 2, i = l, j = r;
      while (i <= j) {
        while (num[i] < num[mid]) {
          ++i;
        }
        while (num[j] > num[mid]) {
          --j;
        }
        if (i <= j) {
          swap(num[i],num[j]);
          ++i,--j;
        }
      }
      if (k == i - l)
        return num[i - 1];
      else if (k < i - l)
        return selectK(num, k, l, i -1);
      else if (k == j + 1 - l)
        return num[j + 1];
      else
        return selectK(num, k - (j - l + 2), j + 2, r);
    }
    void pathcompress(char* str) {
      int i = 0, j = 0;
    
      char prev = '';
      stack<int> offset;
      offset.push(0);
      while(str[i]) {
        if (prev == '/') {
            if (str[i] == '.' && (str[i + 1] == '/' || str[i + 1] == '')) {
              prev = str[i + 1], i += 1;
            }
            else if (str[i] == '.' && str[i + 1] == '.' && (str[i + 2] == '/' || str[i + 2] == '')) {
              i += 2;
              if (offset.empty()) {
                cout << "error" << endl;
                return;            
              }
              j = offset.top();
              offset.pop();
              if (offset.empty() && str[0] == '/') {
                cout << "error" << endl;
                return;
              }
            }
            else if (str[i] == '/') {
              prev = str[i++];
            }
            else {
              offset.push(j);
              prev = str[i];
              str[j++] = str[i++];        
            }
        }
        else {
          prev = str[i];
          str[j++] = str[i++];
        }
      }
      if (j >=3 && str[j - 1] == '/' && str[j-2] == '/')
        str[j-2] = '';
      else if (j >= 2 && str[j - 1] == '/')
        str[j-1] = '';
      else
        str[j] = '';
      if (str[0] == ''){
        str[0] = '.';
        str[1] = '';
      }
        
    }
    
    
    int main()
    {
      int num[] = {3,2,1,4,5};
      int res1 = selectK(num, 1, 0, 4);
      int res2 = selectK(num, 2, 0, 4);
      int res3 = selectK(num, 3, 0, 4);
      int res4 = selectK(num, 4, 0, 4);
      int res5 = selectK(num, 5, 0, 4);
     // int res6 = selectK(num, 6, 0, 4);
    
      //char str[] = "////";
      char str[] = "/.abc/xxx./abc/bacd/.././bcd/fsgs/../../../x/y/z/../../../..";
      pathcompress(str);
      printf("%s
    ",str);
    
      return 0;
    }

    BUT this isn't right, For example: char str[] = "../../../etc/xyz/../abc"; You couldn't print error here. The right solution is:

    You must distinguish the differences with the headers ../ and dir/

    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <limits.h>
    #include <assert.h>
    #include <stack>
    using namespace std;
    int selectK(int num[], int k, int l, int r) {
      
      assert(k <= (r - l + 1) && k >= 1);
      int mid = (l + r) / 2, i = l, j = r;
      while (i <= j) {
        while (num[i] < num[mid]) {
          ++i;
        }
        while (num[j] > num[mid]) {
          --j;
        }
        if (i <= j) {
          swap(num[i],num[j]);
          ++i,--j;
        }
      }
      if (k == i - l)
        return num[i - 1];
      else if (k < i - l)
        return selectK(num, k, l, i -1);
      else if (k == j + 1 - l)
        return num[j + 1];
      else
        return selectK(num, k - (j - l + 2), j + 2, r);
    }
    
    void pathcompress2(char* str) {
      stack<int> path;
      int i = 0, j = 0;
      bool isRoot = (str[0] == '/');
      char prev = '';
      int len = strlen(str);
    
      if (!(len >= 3 && str[0] == '.' && str[1] == '.' && str[2] == '/'))
        path.push(0);
      while(str[i]) {
        if (prev == '/') {
          if (str[i] == '.' && (str[i+1] == '/' || str[i+1] == '')) {
            prev = '/';
    
            if (str[i+1] == '') {
              str[j] = '';
              break;
            }
            i+=2;
          }
          else if (str[i] == '.' && str[i+1] == '.' && (str[i+2] == '/' || str[i+2] == '')) {
            if (path.empty()) {
              str[j++] = str[i];
              str[j++] = str[i+1];
              str[j++] = str[i+2];        
              prev = '/';
    
              if (str[i+2] == '') {
                str[j] = '';
                break;
              }
              i+=3;
            }
            else {
              j = path.top();
              path.pop();
    
              if (path.empty() && isRoot) {  //  The case : cd /..
                printf("Error
    ");
                return;
              }
              if (str[i+2] == '') {
                str[j] = '';
                break;
              }
              prev = '/';
              i += 3;
            }
          }
          else if (str[i] == '/')
            prev = str[i++];
          else {
            prev = str[i];
            path.push(j);
            str[j++] = str[i++];
          } 
        }
        else {
          prev = str[i];
          str[j++] = str[i++];
        }
      }
    
      if (j >= 2 && str[j - 1] == '/')
        str[j-1] = '';
      else
        str[j] = '';
      if (str[0] == ''){
        str[0] = '.';
        str[1] = '';
      }
    
    }
    
    int main()
    {
      int num[] = {3,2,1,4,5};
      int res1 = selectK(num, 1, 0, 4);
      int res2 = selectK(num, 2, 0, 4);
      int res3 = selectK(num, 3, 0, 4);
      int res4 = selectK(num, 4, 0, 4);
      int res5 = selectK(num, 5, 0, 4);
     // int res6 = selectK(num, 6, 0, 4);
    
    
    
      char str[] = "/.abc/xxx./abc/bacd/.././bcd/fsgs/../../../x/y/z/../../../../.././././xda";
      //char str[] = "asdf/.abc/xxx./abc/bacd/.././bcd/fsgs/../../../x/y/z/../../../../../../.././../.././././";
      //char str[] = "/xyz/./bcd/fsgs/../../../x/y/z/../../../..";
      //char str[] = "../../../etc/xyz/../abc/////////////////////////////.asdf/../../../../";
    
      pathcompress2(str);
      printf("%s
    ",str);
    
    
      return 0;
    }

    The concise version is :

    void pathcompress2(char* str) {
      stack<int> path;
      int i = 0, j = 0, len = strlen(str);
      bool isRoot = (str[0] == '/');
      char prev = '';
      if (!(len >= 3 && str[0] == '.' && str[1] == '.' && (str[2] == '/' || str[2] == ''))
        path.push(0);
      while(str[i]) {
        if (prev == '/') {
          if (str[i] == '.' && (str[i+1] == '/' || str[i+1] == '')) {
            prev = '/';
            if (str[i+1] == '') {
              str[j] = '';
              break;
            }
            i+=2;
          }
          else if (str[i] == '.' && str[i+1] == '.' && (str[i+2] == '/' || str[i+2] == '')) {
            if (path.empty()) {
              str[j++] = str[i],str[j++] = str[i+1],str[j++] = str[i+2],prev = '/';
            }
            else {
              j = path.top();
              path.pop();
              if (path.empty() && isRoot) {  //  The case : cd /..
                printf("Error
    ");
                return;
              }
            }
            if (str[i+2] == '') {
              str[j] = '';
              break;
            }
            prev = '/',i += 3;
          }
          else if (str[i] == '/')
            prev = str[i++];
          else {
            prev = str[i],path.push(j),str[j++] = str[i++];
          } 
        }
        else {
          prev = str[i],str[j++] = str[i++];
        }
      }  
      if (j >= 2 && str[j - 1] == '/')
        str[j-1] = '';
      else
        str[j] = '';
      if (str[0] == ''){
        str[0] = '.',str[1] = '';
      }
    }


  • 相关阅读:
    五子棋
    纯ASP实现的“无刷新”聊天室
    砸砖块
    ASP.NET中批量插入数据
    判断一个dataset的数据是否包含另一个dataset的数据
    使用DB2时的一些问题
    RTOS,什么是硬实时和软实时
    异或运算^的一个作用
    vc 重启和关机
    About DLL
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6941629.html
Copyright © 2011-2022 走看看