简化linux风格路径,精简Linux文件路径

精简Linux的文件路径:

..回退的功能

.留在当前文件夹

//仅仅保留一个/

abc/..要返回.

报错

删除最后一个/

主要思路: 用栈记录路径的起始位置,讨论/后的不同情况就可以:

#include

#include

#include

#include

#include

#include

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 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

#include

#include

#include

#include

#include

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 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 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';

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值