精简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
随机推荐
- bzoj4034: [HAOI2015]树上操作(树剖)
4034: [HAOI2015]树上操作 题目:传送门 题解: 树剖裸题: 麻烦一点的就只有子树修改(其实一点也不),因为子树编号连续啊,直接改段(记录编号最小和最大) 开个long long 水模版 ...
- base64对文件进行加密
将原文件读取为字节数组,然后用base64加密,得到加密的字符串 https://stackoverflow.com/questions/475421/base64-encode-a-pdf-in-c ...
- 抽象工厂模式(AbsFactory)C++实现
模式意图:提供一个创建一系列相关或相互依赖对象的接口,二无需指定他们具体的类. 效果: 分离了具体的类. 使 a.客户与类的实现分离 b.客户通过抽象接口操纵实例 c.产品的类名在实现中 ...
- 如何在Linux下添加自己的驱动
在此Linux驱动开发采用网络的方式,介绍两种驱动开发的方法:一.驱动编译到内核 1.先选择一个放置驱动代码的位置,例:drivers/char/xxx.c 2.在drivers/char/Kconf ...
- Android ToolBar标题文字居中的方法
在项目的开发中,使用苹果手机的产品,出的界面效果图极有可能(我这里是一定)完全是按照苹果的界面风格来出的,例如界面顶部的title文字位置是水平居中 如图: 那么问题来了,当我们使用ToolBar控件 ...
- Android中图片旋转
Activity_main.xml文件配置 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/androi ...
- SQLite Tips
附加数据库 Attach database filename as database_name; 主数据库默认为 "Main", 在使用Attach命令时, 不能将database ...
- LINQ(Language Integrated Query)
LINQ http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html LINQ是.NET Framework 3.5的新特性,其全称 ...
- JS 九九运算表
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- java中String和int的互相转化
1. String 转 int 方式1:Integer.parseInt(); 方式2: Integer.valueOf(myStr).intValue(); 2. int 转String 方式1: ...