链接:1410. HTML 实体解析器
这题本来对于 java
、py
选手来讲,直接库函数 replace
一行搞定了…对于 C++
选手就老老实实的进行字符串匹配、替换吧。简单说下思路:
map
将 HTML
字符实体与对应字符进行一个匹配存储map
中所有的字符实体,再遍历字符串 text
进行匹配查找string
对象的 substr
方法进行快速定位查找,匹配成功则直接用 replace
方法进行替换即可思路很明确,几个 API
的熟练应用也是需要掌握的
但是:这个题暴露出的注意点很多很多…
text.size() - s + 1
字符串对象的 size()
方法返回值类型是 unsigned int
这就直接导致了运算结果为负数时判断条件的失效,是一个很易错的知识点">"
由于 &
的替代嵌套到下一层,导致继续替代,导致结果为 >
。这显然是错误的输出,一开始竞赛时好像这个测试用例是存在的。后来经过修正了。这个需要注意,而我在这采用的方法就是给 {"&","&\t"}
增加后续的标志位,再对结果进行删除即可。但是这个方法需要标志位不能与原有效数字起冲突,这个需要注意。这是一个简单的处理方法,也正是因为它的简单,导致了其并不安全。例如:采用一般的后缀标志位如:@、#
均是无法通过测试样例的。参见代码如下:
// 执行用时 :1992 ms, 在所有 C++ 提交中击败了100.00%的用户
// 内存消耗 :16.6 MB, 在所有 C++ 提交中击败了100.00%的用户
class Solution {
public:
map<string,string> m={{""","\""},
{"'","'"},
{">",">"},
{"<","<"},
{"⁄","/"},
{"&","&\t"}};
string entityParser(string text) {
for (auto e : m) {
string c = e.first;
int s = c.size();
int n = text.size();
if (s > n) continue;
// 每次替换size会变化,不能使用 n
// text.size() - s + 1时无符号整数,负数会很大,使得判断失效
for (int i = 0; i < (int)(text.size() - s + 1); ++i) {
if (c == text.substr(i, s)) {
text = text.replace(i, s, e.second);
}
}
}
text.erase(remove(text.begin(), text.end(), '\t'), text.end());
return text;
}
};