精简Linux文件路径
精简Linux的文件路径:
- ..回退的功能
- .留在当前文件夹
- //仅仅保留一个/
- abc/..要返回.
- 报错
- 删除最后一个/
#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:
#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';
}
}
精简Linux文件路径的更多相关文章
- Linux 文件路径包含特殊字符的处理方式
文件路径包含特殊字符的处理方式 1)只用转义符 \ 2)使用双引号 mv /home/".Sent Items"/ /home/".&XfJT0ZABkK5O9g ...
- 截取linux文件存储路径方法
1.截取linux文件存储路径方法 package com.tydic.eshop.action.freemarker; public class dddd { public static void ...
- 【linux下查看文件路径--jdk】
1.which java 首先输入命令行,查看结果: [root@localhost ~]# which java /usr/bin/java PS:which Java是无法定位到Java的安装路径 ...
- Linux下如何查看tomcat是否安装、启动、文件路径、进程ID
Linux下如何查看tomcat是否安装.启动.文件路径.进程ID 在Linux系统下,Tomcat使用命令的操作! 检测是否有安装了Tomcat: rpm -qa|grep tomcat 查看Tom ...
- linux sed命令查询结果前后批量追加内容(html文件批量修改css,js等文件路径)
1.需求:linux使用shell命令查询结果前后批量追加内容 例如:我需要在当前目录下所有的css文件路径前追加域名 我想的是用sed替换去实现,鲍哥的思路是用for循环 1.1方法1:鲍哥的for ...
- 关于File.separator 文件路径:window与linux下路径问题(“No such file or diretory ”异常解决方案)
最近有个在页面上传Excel文件至服务器指定目录并进行数据校验.最后入库及进行进一步处理的应用情境,我写好代码在模拟环境下测试,完全没问题:但客户试用的时候,却老是报告“No such file or ...
- linux whereis-查找二进制程序、代码等相关文件路径
推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 whereis命令用来定位指令的二进制程序.源代码文件和man手册页等相关文件的路径. whereis命令只能用于程序名的搜索,而且 ...
- Linux库文件路径的添加
库文件在连接(静态库和共享库)和运行(仅限于使用共享库的程序)时被使用,其搜索路径是在系统中进行设置的.一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径,所以使用 ...
- linux 头文件路径
linux 头文件路径 /usr/include
随机推荐
- Spark MLlib介绍
Spark MLlib介绍 Spark之所以在机器学习方面具有得天独厚的优势,有以下几点原因: (1)机器学习算法一般都有很多个步骤迭代计算的过程,机器学习的计算需要在多次迭代后获得足够小的误差或者足 ...
- [BZOJ 2100] Apple Delivery
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2100 [算法] Answer = min{ dist(PB,PA1) + dist( ...
- Spring Boot 版本支持对应JDK
转自:http://www.cnblogs.com/oumi/p/9241424.html 一.Spring Boot 版本支持 Spring Boot Spring Framework Java M ...
- shp系列(二)——利用C++进行shp文件的读(打开)
1.各数据类型及其字节数 BYTE 1; char 1; short 2; int 4; double 8; 2.位序big和little及其转换 对于位序是big的 ...
- c++对象关系映射(ORM)框架
ORM(Object Relational Mapping, 对象关系映射),用来将基于对象的数据结构映射到SQL的数据结构中,即将基于对象的数据映射到关系表中的字段,然后我们可以通过对象提供的接口来 ...
- Npgsql使用入门(一)【搭建环境】
首先去官网下载最新数据库安装包 postgresql-9.6.1-1-windows-x64 将postgreSQL9.6注册为windows服务 注意:大小写要正确 D:\Worksoftware\ ...
- JavaScript命名空间的理解与实现
命名空间有效防止函数名/类名和其他人的冲突,在使用多个第三方框架或类库的时候,一旦冲突,唯一能作的就是放弃其中一个.从事Web开发不可避免要接触JavaScript,目前最新版本的JavaScript ...
- 第5章分布式系统模式 在 .NET 中使用 DataSet 实现 Data Transfer Object
要在 .NET Framework 中实现分布式应用程序.客户端应用程序需要显示一个窗体,该窗体要求对 ASP.NET Web Service 进行多个调用以满足单个用户请求.基于性能方面的考虑,我们 ...
- 创建我们第一个Monad
上一篇中介绍了如何使用amplified type, 如IEnumerable<T>,如果我们能找到组合amplified type函数的方法,就会更容易写出强大的程序. 我们已经说了很多 ...
- ubuntu 安装 OpenCV-CUDA
参考链接:http://www.cnblogs.com/platero/p/3993877.html 官方指导:https://help.ubuntu.com/community/OpenCV 0.这 ...