Skip to content

Commit 284be75

Browse files
committed
feat: add solutions to lc problem: No.0591
No.0591.Tag Validator
1 parent 7bd9546 commit 284be75

File tree

4 files changed

+340
-5
lines changed

4 files changed

+340
-5
lines changed

solution/0500-0599/0591.Tag Validator/README.md

+117-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626

2727
<strong>输出:</strong> True
2828

29-
<strong>解释:</strong>
29+
<strong>解释:</strong>
3030

3131
代码被包含在了闭合的标签内: &lt;DIV&gt;&lt;/DIV&gt;
3232

33-
TAG_NAME 是合法的,TAG_CONTENT 包含了一些字符和 cdata 。
33+
TAG_NAME 是合法的,TAG_CONTENT 包含了一些字符和 cdata 。
3434

3535
即使 CDATA_CONTENT 含有不匹配的起始标签和不合法的 TAG_NAME,它应该被视为普通的文本,而不是标签。
3636

@@ -249,6 +249,121 @@ public:
249249
};
250250
```
251251

252+
### **Go**
253+
254+
```go
255+
func isValid(code string) bool {
256+
var stk []string
257+
for i := 0; i < len(code); i++ {
258+
if i > 0 && len(stk) == 0 {
259+
return false
260+
}
261+
if strings.HasPrefix(code[i:], "<![CDATA[") {
262+
n := strings.Index(code[i+9:], "]]>")
263+
if n == -1 {
264+
return false
265+
}
266+
i += n + 11
267+
} else if strings.HasPrefix(code[i:], "</") {
268+
if len(stk) == 0 {
269+
return false
270+
}
271+
j := i + 2
272+
n := strings.IndexByte(code[j:], '>')
273+
if n == -1 {
274+
return false
275+
}
276+
t := code[j : j+n]
277+
last := stk[len(stk)-1]
278+
stk = stk[:len(stk)-1]
279+
if !check(t) || last != t {
280+
return false
281+
}
282+
i += n + 2
283+
} else if strings.HasPrefix(code[i:], "<") {
284+
j := i + 1
285+
n := strings.IndexByte(code[j:], '>')
286+
if n == -1 {
287+
return false
288+
}
289+
t := code[j : j+n]
290+
if !check(t) {
291+
return false
292+
}
293+
stk = append(stk, t)
294+
i += n + 1
295+
}
296+
}
297+
return len(stk) == 0
298+
}
299+
300+
func check(tag string) bool {
301+
n := len(tag)
302+
if n < 1 || n > 9 {
303+
return false
304+
}
305+
for _, c := range tag {
306+
if c < 'A' || c > 'Z' {
307+
return false
308+
}
309+
}
310+
return true
311+
}
312+
```
313+
314+
### **Rust**
315+
316+
```rust
317+
impl Solution {
318+
pub fn is_valid(code: String) -> bool {
319+
fn check(tag: &str) -> bool {
320+
let n = tag.len();
321+
n >= 1 && n <= 9 && tag.as_bytes().iter().all(|b| b.is_ascii_uppercase())
322+
}
323+
324+
let mut stk = Vec::new();
325+
let mut i = 0;
326+
while i < code.len() {
327+
if i > 0 && stk.is_empty() {
328+
return false;
329+
}
330+
if code[i..].starts_with("<![CDATA[") {
331+
match code[i + 9..].find("]]>") {
332+
Some(n) => i += n + 11,
333+
None => return false,
334+
};
335+
} else if code[i..].starts_with("</") {
336+
let j = i + 2;
337+
match code[j..].find('>') {
338+
Some(n) => {
339+
let t = &code[j..j + n];
340+
if !check(t) || stk.is_empty() || stk.pop().unwrap() != t {
341+
return false;
342+
}
343+
i += n + 2;
344+
}
345+
None => return false,
346+
};
347+
} else if code[i..].starts_with("<") {
348+
let j = i + 1;
349+
match code[j..].find('>') {
350+
Some(n) => {
351+
let t = &code[j..j + n];
352+
if !check(t) {
353+
return false;
354+
}
355+
stk.push(t);
356+
}
357+
None => return false,
358+
};
359+
}
360+
i += 1;
361+
}
362+
stk.is_empty()
363+
}
364+
}
365+
```
366+
252367
### **...**
253368

254369
```

solution/0500-0599/0591.Tag Validator/README_EN.md

+118-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
<pre>
2626
<strong>Input:</strong> code = &quot;&lt;DIV&gt;This is the first line &lt;![CDATA[&lt;div&gt;]]&gt;&lt;/DIV&gt;&quot;
2727
<strong>Output:</strong> true
28-
<strong>Explanation:</strong>
29-
The code is wrapped in a closed tag : &lt;DIV&gt; and &lt;/DIV&gt;.
30-
The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata.
28+
<strong>Explanation:</strong>
29+
The code is wrapped in a closed tag : &lt;DIV&gt; and &lt;/DIV&gt;.
30+
The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata.
3131
Although CDATA_CONTENT has an unmatched start tag with invalid TAG_NAME, it should be considered as plain text, not parsed as a tag.
3232
So TAG_CONTENT is valid, and then the code is valid. Thus return true.
3333
</pre>
@@ -215,6 +215,121 @@ public:
215215
};
216216
```
217217

218+
### **Go**
219+
220+
```go
221+
func isValid(code string) bool {
222+
var stk []string
223+
for i := 0; i < len(code); i++ {
224+
if i > 0 && len(stk) == 0 {
225+
return false
226+
}
227+
if strings.HasPrefix(code[i:], "<![CDATA[") {
228+
n := strings.Index(code[i+9:], "]]>")
229+
if n == -1 {
230+
return false
231+
}
232+
i += n + 11
233+
} else if strings.HasPrefix(code[i:], "</") {
234+
if len(stk) == 0 {
235+
return false
236+
}
237+
j := i + 2
238+
n := strings.IndexByte(code[j:], '>')
239+
if n == -1 {
240+
return false
241+
}
242+
t := code[j : j+n]
243+
last := stk[len(stk)-1]
244+
stk = stk[:len(stk)-1]
245+
if !check(t) || last != t {
246+
return false
247+
}
248+
i += n + 2
249+
} else if strings.HasPrefix(code[i:], "<") {
250+
j := i + 1
251+
n := strings.IndexByte(code[j:], '>')
252+
if n == -1 {
253+
return false
254+
}
255+
t := code[j : j+n]
256+
if !check(t) {
257+
return false
258+
}
259+
stk = append(stk, t)
260+
i += n + 1
261+
}
262+
}
263+
return len(stk) == 0
264+
}
265+
266+
func check(tag string) bool {
267+
n := len(tag)
268+
if n < 1 || n > 9 {
269+
return false
270+
}
271+
for _, c := range tag {
272+
if c < 'A' || c > 'Z' {
273+
return false
274+
}
275+
}
276+
return true
277+
}
278+
```
279+
280+
### **Rust**
281+
282+
```rust
283+
impl Solution {
284+
pub fn is_valid(code: String) -> bool {
285+
fn check(tag: &str) -> bool {
286+
let n = tag.len();
287+
n >= 1 && n <= 9 && tag.as_bytes().iter().all(|b| b.is_ascii_uppercase())
288+
}
289+
290+
let mut stk = Vec::new();
291+
let mut i = 0;
292+
while i < code.len() {
293+
if i > 0 && stk.is_empty() {
294+
return false;
295+
}
296+
if code[i..].starts_with("<![CDATA[") {
297+
match code[i + 9..].find("]]>") {
298+
Some(n) => i += n + 11,
299+
None => return false,
300+
};
301+
} else if code[i..].starts_with("</") {
302+
let j = i + 2;
303+
match code[j..].find('>') {
304+
Some(n) => {
305+
let t = &code[j..j + n];
306+
if !check(t) || stk.is_empty() || stk.pop().unwrap() != t {
307+
return false;
308+
}
309+
i += n + 2;
310+
}
311+
None => return false,
312+
};
313+
} else if code[i..].starts_with("<") {
314+
let j = i + 1;
315+
match code[j..].find('>') {
316+
Some(n) => {
317+
let t = &code[j..j + n];
318+
if !check(t) {
319+
return false;
320+
}
321+
stk.push(t);
322+
}
323+
None => return false,
324+
};
325+
}
326+
i += 1;
327+
}
328+
stk.is_empty()
329+
}
330+
}
331+
```
332+
218333
### **...**
219334

220335
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
func isValid(code string) bool {
2+
var stk []string
3+
for i := 0; i < len(code); i++ {
4+
if i > 0 && len(stk) == 0 {
5+
return false
6+
}
7+
if strings.HasPrefix(code[i:], "<![CDATA[") {
8+
n := strings.Index(code[i+9:], "]]>")
9+
if n == -1 {
10+
return false
11+
}
12+
i += n + 11
13+
} else if strings.HasPrefix(code[i:], "</") {
14+
if len(stk) == 0 {
15+
return false
16+
}
17+
j := i + 2
18+
n := strings.IndexByte(code[j:], '>')
19+
if n == -1 {
20+
return false
21+
}
22+
t := code[j : j+n]
23+
last := stk[len(stk)-1]
24+
stk = stk[:len(stk)-1]
25+
if !check(t) || last != t {
26+
return false
27+
}
28+
i += n + 2
29+
} else if strings.HasPrefix(code[i:], "<") {
30+
j := i + 1
31+
n := strings.IndexByte(code[j:], '>')
32+
if n == -1 {
33+
return false
34+
}
35+
t := code[j : j+n]
36+
if !check(t) {
37+
return false
38+
}
39+
stk = append(stk, t)
40+
i += n + 1
41+
}
42+
}
43+
return len(stk) == 0
44+
}
45+
46+
func check(tag string) bool {
47+
n := len(tag)
48+
if n < 1 || n > 9 {
49+
return false
50+
}
51+
for _, c := range tag {
52+
if c < 'A' || c > 'Z' {
53+
return false
54+
}
55+
}
56+
return true
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
impl Solution {
2+
pub fn is_valid(code: String) -> bool {
3+
fn check(tag: &str) -> bool {
4+
let n = tag.len();
5+
n >= 1 && n <= 9 && tag.as_bytes().iter().all(|b| b.is_ascii_uppercase())
6+
}
7+
8+
let mut stk = Vec::new();
9+
let mut i = 0;
10+
while i < code.len() {
11+
if i > 0 && stk.is_empty() {
12+
return false;
13+
}
14+
if code[i..].starts_with("<![CDATA[") {
15+
match code[i + 9..].find("]]>") {
16+
Some(n) => i += n + 11,
17+
None => return false,
18+
};
19+
} else if code[i..].starts_with("</") {
20+
let j = i + 2;
21+
match code[j..].find('>') {
22+
Some(n) => {
23+
let t = &code[j..j + n];
24+
if !check(t) || stk.is_empty() || stk.pop().unwrap() != t {
25+
return false;
26+
}
27+
i += n + 2;
28+
}
29+
None => return false,
30+
};
31+
} else if code[i..].starts_with("<") {
32+
let j = i + 1;
33+
match code[j..].find('>') {
34+
Some(n) => {
35+
let t = &code[j..j + n];
36+
if !check(t) {
37+
return false;
38+
}
39+
stk.push(t);
40+
}
41+
None => return false,
42+
};
43+
}
44+
i += 1;
45+
}
46+
stk.is_empty()
47+
}
48+
}

0 commit comments

Comments
 (0)