bfs icon indicating copy to clipboard operation
bfs copied to clipboard

Update namespace.cc: re-implement the member function NormalizePath

Open ToWorld opened this issue 9 years ago • 0 comments

Update namespace.cc: re-implement the member function NormalizePath. There are some tests below. image 算法说明: `算法伪代码: std::string NameSpace::NormalizePath(const std::string& path) { // 存放标准化后的路径 std::string ret; // 处理边界条件 if (path.empty() || path[0] != '/') { ret = "/"; } // 算法的主循环 // 每次连续处理两个字符 // 为什么选择连续处理两个字符,而不是一个,或者三个或者更多 // 这个主要和函数所要处理的问题相关,本函数主要是想将(用户) // 输入的路径进行标准化,如: // "home" --> "/home" // "" --> "/" // "///" --> "/" // "home//baidu///" --> "/home/baidu" // etc. // 那么本算法的主要是想就是,每次处理连续两个字符, // 并且当前索引index指向连续两个字符的后一个字符 // 那么此时index的值初始化为1 for (uint32_t index = 1; i < path.size(); ) { // 若当前索引对应的字符不是'/', 那么我们可以完全将当前 // 连续的两个字符存储起来 if (path[index] != '/') { ret.push_back(path[index-1]); ret.push_back(path[index]); // 此时index需要跳2段 index += 2; } else { // 当前索引对应的字符是'/',那么我们就需要知道,当前 // 字符的左边和右边各是什么字符,首先我们处理当前字符的 // 左边的字符,若不是'/', 存储,否则忽略, // 而当前字符的后一个字符是什么,当前字符不能知道,则当前 // 字符先不处理,此时跳1段 if (path[index-1] != '/') { ret.push_back(path[index-1]); } index++; } } // 很容易知道,上面的主循环由于索引会跳2段,或者索引初始化为1,会导致源字符串中的 // 最后一个字符不会被处理,比如: // "a", "/", "/aa", "///" // 最后我们处理这种情况 // 这个时候只需要处理一个可能,判断最后一个字符是否为'/',不是则存储,是的话,则忽略。 // 但是这里会遗漏一个test,即"/",我们在后面还会加一个来弥补 if (index == len && path[index-1]!='/') { ret.push_back(path[index-1]); } if (ret.empty()) { ret = "/"; } return ret; }

` 下面说说为什么这个算法比每次处理一个字符效率要高,

  1. 首先一个用户输入的路径,基本上就是可能是"home/"; "//", "/baidu/"等情况,不太可能会遇到"//////////"这种情况, 若遇到后面一种极端的情况,那么本算法可能就和每次处理一个字符效率相当了。所以我们还是考虑正常的情况,这个时候 若非"/"字符所占的比例越高,每次处理两个字符的效率就越高,不过永远不会超越每次处理一个字符的50%,因为本算法每次 都是处理两个字符。 经过初步测试,效率的确提高不少。 欢迎大家提出更好的方法。

ToWorld avatar Jan 09 '17 08:01 ToWorld