From 712c82aba944554a8569806cbc112f71ebc4aff7 Mon Sep 17 00:00:00 2001 From: Lam Haoyin Date: Thu, 6 Jan 2022 02:00:30 +0800 Subject: [PATCH] add: 220106-CN --- 2201/220106-CN.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++ 2201/CMakeLists.txt | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 2201/220106-CN.cpp diff --git a/2201/220106-CN.cpp b/2201/220106-CN.cpp new file mode 100644 index 0000000..63895e1 --- /dev/null +++ b/2201/220106-CN.cpp @@ -0,0 +1,91 @@ +#include +#include +#include +#include + +/** + * 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 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; +} \ No newline at end of file diff --git a/2201/CMakeLists.txt b/2201/CMakeLists.txt index daff41d..106d2b6 100644 --- a/2201/CMakeLists.txt +++ b/2201/CMakeLists.txt @@ -3,4 +3,4 @@ PROJECT(2201) SET(CMAKE_CXX_STANDARD 23) -ADD_EXECUTABLE(2201 220105.cpp) \ No newline at end of file +ADD_EXECUTABLE(2201 220106-CN.cpp) \ No newline at end of file