精简Linux文件路径

来源:互联网 发布:js中转换日期格式 编辑:程序博客网 时间:2024/05/14 09:36

精简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 = '\0';  stack<int> offset;  offset.push(0);  while(str[i]) {    if (prev == '/') {        if (str[i] == '.' && (str[i + 1] == '/' || str[i + 1] == '\0')) {          prev = str[i + 1], i += 1;        }        else if (str[i] == '.' && str[i + 1] == '.' && (str[i + 2] == '/' || str[i + 2] == '\0')) {          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] = '\0';  else if (j >= 2 && str[j - 1] == '/')    str[j-1] = '\0';  else    str[j] = '\0';  if (str[0] == '\0'){    str[0] = '.';    str[1] = '\0';  }    }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\n",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 = '\0';  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] == '\0')) {        prev = '/';        if (str[i+1] == '\0') {          str[j] = '\0';          break;        }        i+=2;      }      else if (str[i] == '.' && str[i+1] == '.' && (str[i+2] == '/' || str[i+2] == '\0')) {        if (path.empty()) {          str[j++] = str[i];          str[j++] = str[i+1];          str[j++] = str[i+2];                  prev = '/';          if (str[i+2] == '\0') {            str[j] = '\0';            break;          }          i+=3;        }        else {          j = path.top();          path.pop();          if (path.empty() && isRoot) {  //  The case : cd /..            printf("Error\n");            return;          }          if (str[i+2] == '\0') {            str[j] = '\0';            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] = '\0';  else    str[j] = '\0';  if (str[0] == '\0'){    str[0] = '.';    str[1] = '\0';  }}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\n",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 = '\0';  if (!(len >= 3 && str[0] == '.' && str[1] == '.' && (str[2] == '/' || str[2] == '\0'))    path.push(0);  while(str[i]) {    if (prev == '/') {      if (str[i] == '.' && (str[i+1] == '/' || str[i+1] == '\0')) {        prev = '/';        if (str[i+1] == '\0') {          str[j] = '\0';          break;        }        i+=2;      }      else if (str[i] == '.' && str[i+1] == '.' && (str[i+2] == '/' || str[i+2] == '\0')) {        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\n");            return;          }        }        if (str[i+2] == '\0') {          str[j] = '\0';          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] = '\0';  else    str[j] = '\0';  if (str[0] == '\0'){    str[0] = '.',str[1] = '\0';  }}


1 0
原创粉丝点击