题目

标题和出处

标题:HTML 实体解析器

出处:1410. HTML 实体解析器

难度

6 级

题目描述

要求

「HTML 实体解析器」是一种特殊的解析器,它将 HTML 代码作为输入,并用字符本身替换掉所有这些特殊的字符实体。

HTML 里这些特殊字符和它们对应的字符实体包括:

  • 双引号:字符实体为 字符串题目:HTML 实体解析器 - 图1,对应的字符是 字符串题目:HTML 实体解析器 - 图2
  • 单引号:字符实体为 字符串题目:HTML 实体解析器 - 图3,对应的字符是 字符串题目:HTML 实体解析器 - 图4
  • 与符号:字符实体为 字符串题目:HTML 实体解析器 - 图5,对应对的字符是 字符串题目:HTML 实体解析器 - 图6
  • 大于号:字符实体为 字符串题目:HTML 实体解析器 - 图7,对应的字符是 字符串题目:HTML 实体解析器 - 图8
  • 小于号:字符实体为 字符串题目:HTML 实体解析器 - 图9,对应的字符是 字符串题目:HTML 实体解析器 - 图10
  • 斜线号:字符实体为 字符串题目:HTML 实体解析器 - 图11,对应的字符是 字符串题目:HTML 实体解析器 - 图12

给你输入字符串 字符串题目:HTML 实体解析器 - 图13,请你实现一个 HTML 实体解析器,返回解析器解析后的结果。

示例

示例 1:

输入:字符串题目:HTML 实体解析器 - 图14
输出:字符串题目:HTML 实体解析器 - 图15
解释:解析器把字符实体 字符串题目:HTML 实体解析器 - 图16字符串题目:HTML 实体解析器 - 图17 替换

示例 2:

输入:字符串题目:HTML 实体解析器 - 图18
输出:字符串题目:HTML 实体解析器 - 图19

示例 3:

输入:字符串题目:HTML 实体解析器 - 图20%22%7D#card=math&code=%5Ctexttt%7Btext%20%3D%20%22Stay%20home%21%20Practice%20on%20Leetcode%20%3A%29%22%7D&id=ERCpO)
输出:字符串题目:HTML 实体解析器 - 图21%22%7D#card=math&code=%5Ctexttt%7B%22Stay%20home%21%20Practice%20on%20Leetcode%20%3A%29%22%7D&id=FKwWm)

示例 4:

输入:字符串题目:HTML 实体解析器 - 图22
输出:字符串题目:HTML 实体解析器 - 图23

示例 5:

输入:字符串题目:HTML 实体解析器 - 图24
输出:字符串题目:HTML 实体解析器 - 图25

数据范围

  • 字符串题目:HTML 实体解析器 - 图26
  • 字符串可能包含 字符串题目:HTML 实体解析器 - 图27 个ASCII 字符中的任意字符。

解法

思路和算法

HTML 中的每个特殊字符的字符实体都以 字符串题目:HTML 实体解析器 - 图28 开始,以 字符串题目:HTML 实体解析器 - 图29 结束,其余字符都是小写字母。对于输入字符串 字符串题目:HTML 实体解析器 - 图30,其中的每一个符合上述特点的子串都可能是特殊字符的字符实体。遍历输入字符串 字符串题目:HTML 实体解析器 - 图31,在遍历的同时解析特殊字符。

理想情况下,字符串题目:HTML 实体解析器 - 图32字符串题目:HTML 实体解析器 - 图33 应该成对出现,但是实际情况不一定成对出现,例如在 字符串题目:HTML 实体解析器 - 图34 之前没有 字符串题目:HTML 实体解析器 - 图35,或者在 字符串题目:HTML 实体解析器 - 图36 之后没有 字符串题目:HTML 实体解析器 - 图37,或者在一个 字符串题目:HTML 实体解析器 - 图38 之前出现两个 字符串题目:HTML 实体解析器 - 图39,因此在从左到右遍历 字符串题目:HTML 实体解析器 - 图40 时,对于每个 字符串题目:HTML 实体解析器 - 图41,应该找到在这个 字符串题目:HTML 实体解析器 - 图42 之前的最后一个 字符串题目:HTML 实体解析器 - 图43(如果存在)作为字符实体的开始。

具体做法是,维护字符实体的开始下标 字符串题目:HTML 实体解析器 - 图44,遍历过程中进行如下操作:

  • 如果遇到 字符串题目:HTML 实体解析器 - 图45,当 字符串题目:HTML 实体解析器 - 图46 时,需要首先将 字符串题目:HTML 实体解析器 - 图47字符串题目:HTML 实体解析器 - 图48 到当前下标前一个位置的字符拼接到解析后的结果,由于 字符串题目:HTML 实体解析器 - 图49 表示字符实体的开始,因此将 字符串题目:HTML 实体解析器 - 图50 设为当前下标;
  • 对于非 字符串题目:HTML 实体解析器 - 图51 的字符,当 字符串题目:HTML 实体解析器 - 图52 时,如果遇到 字符串题目:HTML 实体解析器 - 图53,则遇到一个以 字符串题目:HTML 实体解析器 - 图54 开头和以 字符串题目:HTML 实体解析器 - 图55 结尾的子串,如果该子串是特殊字符的字符实体则将字符实体转换成对应的特殊字符拼接到解析后的结果,否则将该子串直接拼接到解析后的结果,然后令 字符串题目:HTML 实体解析器 - 图56,表示上一个字符实体已经遍历完毕;
  • 对于非 字符串题目:HTML 实体解析器 - 图57 的字符,当 字符串题目:HTML 实体解析器 - 图58 时,当前字符不属于字符实体中的某个字符,因此将当前字符拼接到解析后的结果。

遍历结束后,如果 字符串题目:HTML 实体解析器 - 图59,则将 字符串题目:HTML 实体解析器 - 图60字符串题目:HTML 实体解析器 - 图61 到末尾的字符拼接到解析后的结果。

代码

  1. class Solution {
  2. public String entityParser(String text) {
  3. StringBuffer sb = new StringBuffer();
  4. int length = text.length();
  5. int entityStart = -1;
  6. for (int i = 0; i < length; i++) {
  7. char c = text.charAt(i);
  8. if (c == '&') {
  9. if (entityStart >= 0) {
  10. sb.append(text.substring(entityStart, i));
  11. }
  12. entityStart = i;
  13. } else {
  14. if (entityStart >= 0) {
  15. if (c == ';') {
  16. String entity = text.substring(entityStart, i + 1);
  17. String specialCharacter = getCharacter(entity);
  18. sb.append(specialCharacter);
  19. entityStart = -1;
  20. }
  21. } else {
  22. sb.append(c);
  23. }
  24. }
  25. }
  26. if (entityStart >= 0) {
  27. sb.append(text.substring(entityStart));
  28. }
  29. return sb.toString();
  30. }
  31. public String getCharacter(String entity) {
  32. switch (entity) {
  33. case "&quot;":
  34. return "\"";
  35. case "&apos;":
  36. return "\'";
  37. case "&amp;":
  38. return "&";
  39. case "&gt;":
  40. return ">";
  41. case "&lt;":
  42. return "<";
  43. case "&frasl;":
  44. return "/";
  45. default:
  46. return entity;
  47. }
  48. }
  49. }

复杂度分析

  • 时间复杂度:字符串题目:HTML 实体解析器 - 图62#card=math&code=O%28n%29&id=g4NoA),其中 字符串题目:HTML 实体解析器 - 图63 是字符串 字符串题目:HTML 实体解析器 - 图64 的长度。需要遍历字符串 字符串题目:HTML 实体解析器 - 图65 一次,完成解析和拼接解析后的结果。
  • 空间复杂度:字符串题目:HTML 实体解析器 - 图66#card=math&code=O%28n%29&id=FOEDt),其中 字符串题目:HTML 实体解析器 - 图67 是字符串 字符串题目:HTML 实体解析器 - 图68 的长度。需要额外创建一个长度为 字符串题目:HTML 实体解析器 - 图69#card=math&code=O%28n%29&id=H7F2z) 的 字符串题目:HTML 实体解析器 - 图70字符串题目:HTML 实体解析器 - 图71 类型的对象用于存储解析后的结果。由于 Java 中的 字符串题目:HTML 实体解析器 - 图72 类型的对象不可变,因此空间复杂度至少为 字符串题目:HTML 实体解析器 - 图73#card=math&code=O%28n%29&id=jXa14)。