...
1
2 package misspell
3
4 import (
5 "unicode/utf8"
6 )
7
8
9
10
11
12
13
14 func AlmostEqual(a, b string) bool {
15 for len(a) > 0 && len(b) > 0 {
16 ra, tailA := shiftRune(a)
17 rb, tailB := shiftRune(b)
18 if ra == rb {
19 a, b = tailA, tailB
20 continue
21 }
22
23 if equalValid(a, tailB) || equalValid(tailA, b) || equalValid(tailA, tailB) {
24 return true
25 }
26 if len(tailA) == 0 || len(tailB) == 0 {
27 return false
28 }
29
30 a, b = tailA, tailB
31 Ra, tailA := shiftRune(tailA)
32 Rb, tailB := shiftRune(tailB)
33 return ra == Rb && Ra == rb && equalValid(tailA, tailB)
34 }
35 if len(a) == 0 {
36 return len(b) == 0 || singleRune(b)
37 }
38 return singleRune(a)
39 }
40
41
42 func singleRune(s string) bool {
43 _, n := utf8.DecodeRuneInString(s)
44 return n == len(s)
45 }
46
47
48
49 func shiftRune(s string) (rune, string) {
50 if len(s) == 0 {
51 panic(s)
52 }
53 r, n := utf8.DecodeRuneInString(s)
54 return r, s[n:]
55 }
56
57
58 func equalValid(a, b string) bool {
59 var ra, rb rune
60 for len(a) > 0 && len(b) > 0 {
61 ra, a = shiftRune(a)
62 rb, b = shiftRune(b)
63 if ra != rb {
64 return false
65 }
66 }
67 return len(a) == 0 && len(b) == 0
68 }
69
View as plain text