Open ryanorz opened 6 years ago
Note: no error check, no tag match, just simple enough.
响应号召,代码变成30行以内
#include <string> using namespace std; void formatXML3(const string& input) { int offset = 0; int level = 0; while (offset < input.size()) { int start = offset; if (input[offset] == '<') // 找出 tag offset = input.find_first_of(">", offset+1) + 1; else // 找出 content offset = input.find_first_of("<", offset+1); if (offset == string::npos) // 没找到结尾符号则,则直接偏移到最后 offset = input.size(); // </tag> 结尾标签层级先减一再打印 if (input[start] == '<' && input[start+1] == '/') level--; // 打印 level + tag 或 level + content printf("%s%s\n", string(level*4, ' ').c_str(), input.substr(start, offset-start).c_str()); // <tag> 开始标签打印完层级加一 if (input[start] == '<' && input[start+1] != '/' && input[offset-2] != '/') level++; } } int main(int argc, char* argv[]) { string input = "<a>123<b>456<c/></b></a>"; formatXML3(input); }
以下是原始版代码
#include <string> using namespace std; enum class TokenType { Content, Pretag, Posttag, Fulltag }; string getNextTokenWithoutErrorCheck(string& xmlWithoutFormat, int& offset, TokenType& type) { int size = xmlWithoutFormat.size(); if (offset >= size) return ""; int start = offset; switch (xmlWithoutFormat[start]) { case '<': while (xmlWithoutFormat[offset] != '>') { offset++; } if (xmlWithoutFormat[offset-1] == '/') { type = TokenType::Fulltag; } else if (xmlWithoutFormat[start+1] == '/') { type = TokenType::Posttag; } else { type = TokenType::Pretag; } offset++; break; default: while (xmlWithoutFormat[offset] != '<' && offset < size) { offset++; } type = TokenType::Content; } return xmlWithoutFormat.substr(start, offset - start); } void formatXML(string& xmlWithoutFormat) { int level = 0; int offset = 0; TokenType type; while (true) { string token = getNextTokenWithoutErrorCheck(xmlWithoutFormat, offset, type); if (token.size() == 0) break; switch (type) { case TokenType::Content: case TokenType::Fulltag: { for (int i = 0; i < level; i++) printf("\t"); printf("%s\n", token.c_str()); break; } case TokenType::Pretag: { for (int i = 0; i < level; i++) printf("\t"); printf("%s\n", token.c_str()); level++; break; } case TokenType::Posttag: { level--; for (int i = 0; i < level; i++) printf("\t"); printf("%s\n", token.c_str()); break; } } } } int main(int argc, char* argv[]) { string input = "<a>123<b>456<c/></b></a>"; formatXML(input); }
感觉简化的代码不错啊~ 就是花的时间长了点, 希望压缩在20分钟以内, 另外思路感觉表述的太简单了, 建议在某种情况level该加该减最好说一下
Question_ID: Q001_ryanorz_solution
Language: c++
Time Cost: 40-mins
Time Complexity: O(n)
Solution
Note: no error check, no tag match, just simple enough.
My Code
响应号召,代码变成30行以内
以下是原始版代码
Other