add: 220106-CN

This commit is contained in:
Lam Haoyin 2022-01-06 02:00:30 +08:00
parent cc55911d89
commit 712c82aba9
No known key found for this signature in database
GPG Key ID: 8C089CB1A2B7544F
2 changed files with 92 additions and 1 deletions

91
2201/220106-CN.cpp Normal file
View File

@ -0,0 +1,91 @@
#include <string>
#include <stack>
#include <cstring>
#include <iostream>
/**
* 71. Simplify Path
* Given a string path, which is an absolute path (starting with a slash '/') to a file or directory in a Unix-style file system, convert it to the simplified canonical path.
*
* In a Unix-style file system, a period '.' refers to the current directory, a double period '..' refers to the directory up a level, and any multiple consecutive slashes (i.e. '//') are treated as a single slash '/'. For this problem, any other format of periods such as '...' are treated as file/directory names.
*
* The canonical path should have the following format:
*
* The path starts with a single slash '/'.
* Any two directories are separated by a single slash '/'.
* The path does not end with a trailing '/'.
* The path only contains the directories on the path from the root directory to the target file or directory (i.e., no period '.' or double period '..')
* Return the simplified canonical path.
*/
// Using pointer, in-place
class Solution {
public:
static std::string simplifyPath(const std::string& path) {
char* p = new char[path.length()+1];
std::strcpy(p, path.c_str());
char* r = new char[path.length()+1]{'/'};
for (char* current = std::strtok(p, "/"), *ptr = r; current; current = std::strtok(nullptr, "/")) {
if (!*current || !std::strcmp(".", current))
continue;
if (!std::strcmp("..", current)) {
if (ptr > r)
*ptr-- = 0;
while (ptr > r && *ptr != '/')
*ptr-- = 0;
if (ptr > r && *ptr == '/')
*ptr = 0;
}
else {
*(ptr++) = '/';
while (*ptr++ = *current++);
--ptr;
}
}
delete[] p;
std::string ret(r);
delete[] r;
return ret;
}
};
// Using stack
class SolutionStack {
public:
static std::string simplifyPath(const std::string& path) {
int len = path.length();
const char* pathStr = path.c_str();
int names[3010]{};
int nNames = 0;
for (int pos = 0; pos < len; ) {
for (; pathStr[pos] == '/' && pos < len; ++pos);
names[nNames++] = pos;
for (; pathStr[pos] != '/' && pos < len; ++pos);
names[nNames++] = pos;
}
std::stack<std::string> s;
for (int pos = 0; pos < nNames; pos += 2) {
if (names[pos + 1] - names[pos] == 0)
break;
std::string str(pathStr + names[pos], names[pos + 1] - names[pos]);
if (str == ".") continue;
if (str == "..") {
if (!s.empty())
s.pop();
} else {
s.push("/" + str);
}
}
std::string ret;
while (!s.empty()) {
ret = s.top().append(ret);
s.pop();
}
return ret.empty() ? "/" : ret;
}
};
int main() {
std::cout << Solution::simplifyPath("/a//b////c/d//././/..") << std::endl;
return 0;
}

View File

@ -3,4 +3,4 @@ PROJECT(2201)
SET(CMAKE_CXX_STANDARD 23) SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(2201 220105.cpp) ADD_EXECUTABLE(2201 220106-CN.cpp)