Every day a Leetcode
题目来源:1410. HTML 实体解析器
解法1:模拟
遍历字符串 text,每次遇到 ’&‘,就判断以下情况:
- 双引号:字符实体为 " ,对应的字符是 " 。
- 单引号:字符实体为 ' ,对应的字符是 ’ 。
- 与符号:字符实体为 & ,对应对的字符是 & 。
- 大于号:字符实体为 > ,对应的字符是 > 。
- 小于号:字符实体为 < ,对应的字符是 < 。
- 斜线号:字符实体为 ⁄ ,对应的字符是 / 。
如果是上述情况,将转换结果插入结果;如果都不是,则直接添加到结果里。
代码:
/*
* @lc app=leetcode.cn id=1410 lang=cpp
*
* [1410] HTML 实体解析器
*/
// @lc code=start
class Solution
{
public:
string entityParser(string text)
{
string result;
int i = 0;
while (i < text.size())
{
if (text[i] == '&')
{
if (text.substr(i, 4) == ">")
{
result += '>';
i += 4;
}
else if (text.substr(i, 4) == "<")
{
result += '<';
i += 4;
}
else if (text.substr(i, 5) == "&")
{
result += '&';
i += 5;
}
else if (text.substr(i, 6) == """)
{
result += '"';
i += 6;
}
else if (text.substr(i, 6) == "'")
{
result += '\'';
i += 6;
}
else if (text.substr(i, 7) == "⁄")
{
result += '/';
i += 7;
}
else
result += text[i++];
}
else
result += text[i++];
}
return result;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是字符串 text 的长度。
空间复杂度:O(1)。
解法2:模拟
本题要求把字符串中所有的「字符实体」替换成对应的字符。
「字符实体」都是由 & 开头的,所以我们只需要遍历一遍字符串,用一个变量 pos\textit{pos}pos 表示当前处理的位置,如果 text[pos]=‘&’,就在这个位置进行探测。假设一个「字符实体」为 e,对应的字符为 c,那么可以通过判断 pos 位置开始,长度和 e 相同的子串是否和 e 相等,如果相等就可以替换。
代码:
class Solution {
public:
using EntityChar = pair <string, char>;
vector <EntityChar> entityList;
string entityParser(string text) {
entityList = vector({
(EntityChar){""", '"'},
(EntityChar){"'", '\''},
(EntityChar){"&", '&'},
(EntityChar){">", '>'},
(EntityChar){"<", '<'},
(EntityChar){"⁄", '/'}
});
string r = "";
for (int pos = 0; pos < text.size(); ) {
bool isEntity = false;
if (text[pos] == '&') {
for (const auto &[e, c]: entityList) {
if (text.substr(pos, e.size()) == e) {
r.push_back(c);
pos += e.size();
isEntity = true;
break;
}
}
}
if (!isEntity) {
r.push_back(text[pos++]);
continue;
}
}
return r;
}
};
结果:
复杂度分析:
时间复杂度:O(k×n),其中 n 是字符串 text 的长度。考虑最坏情况,每个位置都是 &,那么每个位置都要进行 6 次探测,探测的总时间代价和「实体字符」的总长度 k 相关,这里 k=6+6+5+4+4+7=32。
空间复杂度:O(k),这里用了 entityList 作为辅助变量,字符总数为 k+6,故渐进空间复杂度为 O(k+6)=O(k)。