Skip to content

Commit

Permalink
Fixed LCS Backtrack/Diff with Unicode inputs + LCS unicode test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
hbollon committed Dec 12, 2020
1 parent 28c4ba0 commit 3674232
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
20 changes: 10 additions & 10 deletions lcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ func LCSBacktrack(str1, str2 string) (string, error) {
return str1, nil
}

return processLCSBacktrack(str1, str2, lcsProcess(runeStr1, runeStr2), len(str1), len(str2)), nil
return processLCSBacktrack(str1, str2, lcsProcess(runeStr1, runeStr2), len(runeStr1), len(runeStr2)), nil
}

func processLCSBacktrack(str1 string, str2 string, lcsMatrix [][]int, m, n int) string {
func processLCSBacktrack(str1, str2 string, lcsMatrix [][]int, m, n int) string {
// Convert strings to rune array to handle no-ASCII characters
runeStr1 := []rune(str1)
runeStr2 := []rune(str2)

if m == 0 || n == 0 {
return ""
} else if runeStr1[m-1] == runeStr2[n-1] {
return processLCSBacktrack(str1, str2, lcsMatrix, m-1, n-1) + string(str1[m-1])
return processLCSBacktrack(str1, str2, lcsMatrix, m-1, n-1) + string(runeStr1[m-1])
} else if lcsMatrix[m][n-1] > lcsMatrix[m-1][n] {
return processLCSBacktrack(str1, str2, lcsMatrix, m, n-1)
}
Expand All @@ -87,10 +87,10 @@ func LCSBacktrackAll(str1, str2 string) ([]string, error) {
return []string{str1}, nil
}

return processLCSBacktrackAll(str1, str2, lcsProcess(runeStr1, runeStr2), len(str1), len(str2)).ToArray(), nil
return processLCSBacktrackAll(str1, str2, lcsProcess(runeStr1, runeStr2), len(runeStr1), len(runeStr2)).ToArray(), nil
}

func processLCSBacktrackAll(str1 string, str2 string, lcsMatrix [][]int, m, n int) utils.StringHashMap {
func processLCSBacktrackAll(str1, str2 string, lcsMatrix [][]int, m, n int) utils.StringHashMap {
// Convert strings to rune array to handle no-ASCII characters
runeStr1 := []rune(str1)
runeStr2 := []rune(str2)
Expand All @@ -102,7 +102,7 @@ func processLCSBacktrackAll(str1 string, str2 string, lcsMatrix [][]int, m, n in
substrings[""] = struct{}{}
} else if runeStr1[m-1] == runeStr2[n-1] {
for key := range processLCSBacktrackAll(str1, str2, lcsMatrix, m-1, n-1) {
substrings[key+string(str1[m-1])] = struct{}{}
substrings[key+string(runeStr1[m-1])] = struct{}{}
}
} else {
if lcsMatrix[m-1][n] >= lcsMatrix[m][n-1] {
Expand All @@ -127,7 +127,7 @@ func LCSDiff(str1, str2 string) ([]string, error) {
return []string{str1}, nil
}

diff := processLCSDiff(str1, str2, lcsProcess(runeStr1, runeStr2), len(str1), len(str2))
diff := processLCSDiff(str1, str2, lcsProcess(runeStr1, runeStr2), len(runeStr1), len(runeStr2))
return diff, nil
}

Expand All @@ -140,17 +140,17 @@ func processLCSDiff(str1 string, str2 string, lcsMatrix [][]int, m, n int) []str

if m > 0 && n > 0 && runeStr1[m-1] == runeStr2[n-1] {
diff = processLCSDiff(str1, str2, lcsMatrix, m-1, n-1)
diff[0] = diff[0] + " " + string(str1[m-1])
diff[0] = diff[0] + " " + string(runeStr1[m-1])
diff[1] = diff[1] + " "
return diff
} else if n > 0 && (m == 0 || lcsMatrix[m][n-1] > lcsMatrix[m-1][n]) {
diff = processLCSDiff(str1, str2, lcsMatrix, m, n-1)
diff[0] = diff[0] + " " + string(str2[n-1])
diff[0] = diff[0] + " " + string(runeStr2[n-1])
diff[1] = diff[1] + " +"
return diff
} else if m > 0 && (n == 0 || lcsMatrix[m][n-1] <= lcsMatrix[m-1][n]) {
diff = processLCSDiff(str1, str2, lcsMatrix, m-1, n)
diff[0] = diff[0] + " " + string(str1[m-1])
diff[0] = diff[0] + " " + string(runeStr1[m-1])
diff[1] = diff[1] + " -"
return diff
}
Expand Down
4 changes: 4 additions & 0 deletions lcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ func TestLCSBacktrack(t *testing.T) {
{"ABCDGH/AEDFHR", args{"ABCDGH", "AEDFHR"}, "ADH", false},
{"AGGTAB/GXTXAYB", args{"AGGTAB", "GXTXAYB"}, "GTAB", false},
{"XMJYAUZ/MZJAWXU", args{"XMJYAUZ", "MZJAWXU"}, "MJAU", false},
{"XMJYAUZ/MZJAWXU", args{"XMJYAUZ", "MZJAWXU"}, "MJAU", false},
{"你好先生/你好夫人", args{"你好先生", "你好夫人"}, "你好", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -86,6 +88,7 @@ func TestLCSBacktrackAll(t *testing.T) {
{"XMJYAUZ/MZJAWXU", args{"XMJYAUZ", "MZJAWXU"}, []string{"MJAU"}, false},
{"AZBYCWDX/ZAYBWCXD", args{"AZBYCWDX", "ZAYBWCXD"}, []string{"ABCD", "ABCX", "ABWD", "ABWX", "AYCD", "AYCX", "AYWD", "AYWX", "ZBCD", "ZBCX", "ZBWD", "ZBWX", "ZYCD", "ZYCX", "ZYWD", "ZYWX"}, false},
{"AATCC/ACACG", args{"AATCC", "ACACG"}, []string{"AAC", "ACC"}, false},
{"您好女士,你好吗?/先生,你好吗?", args{"您好女士 你好吗?", "先生 你好吗?"}, []string{" 你好吗?"}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -118,6 +121,7 @@ func TestLCSDiff(t *testing.T) {
{"empty/AB", args{"", "AB"}, nil, true},
{"AB/AB", args{"AB", "AB"}, []string{"AB"}, false},
{"computer/houseboat", args{"computer", "houseboat"}, []string{" h c o m p u s e b o a t e r", " + - - - + + + + + - -"}, false},
{"您好女士,你好吗?/先生,你好吗?", args{"您好女士 你好吗?", "先生 你好吗?"}, []string{" 先 生 您 好 女 士 你 好 吗 ?", " + + - - - - "}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 3674232

Please sign in to comment.