Skip to content

Commit 05ef99b

Browse files
committed
Small tweaks to text and code
1 parent 0634627 commit 05ef99b

File tree

7 files changed

+256
-272
lines changed

7 files changed

+256
-272
lines changed
Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,46 @@
11
extension String {
2-
func longestCommonSubsequence(other:String) -> String {
3-
4-
func lcsLength(other: String) -> [[Int]] {
5-
var matrix = [[Int]](count:self.characters.count+1, repeatedValue:[Int](count:other.characters.count+1, repeatedValue:0))
6-
7-
for (i, selfChar) in self.characters.enumerate() {
8-
for (j, otherChar) in other.characters.enumerate() {
9-
if (otherChar == selfChar) {
10-
matrix[i+1][j+1] = (matrix[i][j]) + 1
11-
}
12-
else {
13-
matrix[i+1][j+1] = max(matrix[i][j+1], matrix[i+1][j])
14-
}
15-
}
16-
}
17-
18-
return matrix;
2+
public func longestCommonSubsequence(other: String) -> String {
3+
4+
func lcsLength(other: String) -> [[Int]] {
5+
var matrix = [[Int]](count: self.characters.count+1, repeatedValue: [Int](count: other.characters.count+1, repeatedValue: 0))
6+
7+
for (i, selfChar) in self.characters.enumerate() {
8+
for (j, otherChar) in other.characters.enumerate() {
9+
if otherChar == selfChar {
10+
matrix[i+1][j+1] = matrix[i][j] + 1
11+
} else {
12+
matrix[i+1][j+1] = max(matrix[i][j+1], matrix[i+1][j])
13+
}
1914
}
20-
21-
func backtrack(matrix: [[Int]]) -> String {
22-
var i = self.characters.count
23-
var j = other.characters.count
24-
var charInSequence = self.endIndex
25-
26-
var lcs = String()
27-
28-
while (i >= 1 && j >= 1) {
29-
if (matrix[i][j] == matrix[i][j - 1]) {
30-
j = j - 1
31-
}
32-
else if (matrix[i][j] == matrix[i - 1][j]) {
33-
i = i - 1
34-
charInSequence = charInSequence.predecessor()
35-
}
36-
else {
37-
i = i - 1
38-
j = j - 1
39-
charInSequence = charInSequence.predecessor()
40-
41-
lcs.append(self[charInSequence])
42-
}
43-
}
44-
45-
return String(lcs.characters.reverse());
15+
}
16+
return matrix
17+
}
18+
19+
func backtrack(matrix: [[Int]]) -> String {
20+
var i = self.characters.count
21+
var j = other.characters.count
22+
var charInSequence = self.endIndex
23+
24+
var lcs = String()
25+
26+
while i >= 1 && j >= 1 {
27+
if matrix[i][j] == matrix[i][j - 1] {
28+
j -= 1
29+
} else if matrix[i][j] == matrix[i - 1][j] {
30+
i -= 1
31+
charInSequence = charInSequence.predecessor()
32+
} else {
33+
i -= 1
34+
j -= 1
35+
charInSequence = charInSequence.predecessor()
36+
lcs.append(self[charInSequence])
4637
}
47-
48-
return backtrack(lcsLength(other))
38+
}
39+
return String(lcs.characters.reverse())
4940
}
41+
42+
return backtrack(lcsLength(other))
43+
}
5044
}
5145

5246
// Examples
@@ -55,8 +49,10 @@ let a = "ABCBX"
5549
let b = "ABDCAB"
5650
let c = "KLMK"
5751

58-
a.longestCommonSubsequence(c) //""
59-
a.longestCommonSubsequence("") //""
60-
a.longestCommonSubsequence(b) //"ABCB"
61-
b.longestCommonSubsequence(a) //"ABCB"
62-
a.longestCommonSubsequence(a) // "ABCBX"
52+
a.longestCommonSubsequence(c) // ""
53+
a.longestCommonSubsequence("") // ""
54+
a.longestCommonSubsequence(b) // "ABCB"
55+
b.longestCommonSubsequence(a) // "ABCB"
56+
a.longestCommonSubsequence(a) // "ABCBX"
57+
58+
"Hello World".longestCommonSubsequence("Bonjour le monde")

Longest Common Subsequence/LongestCommonSubsequence.playground/timeline.xctimeline

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,69 @@
11
extension String {
2-
func longestCommonSubsequence(other:String) -> String {
3-
4-
// Computes the length of the lcs using dynamic programming
5-
// Output is a matrix of size (n+1)x(m+1), where matrix[x][y] indicates the length
6-
// of lcs between substring (0, x-1) of self and substring (0, y-1) of other.
7-
func lcsLength(other: String) -> [[Int]] {
8-
9-
//Matrix of size (n+1)x(m+1), algorithm needs first row and first column to be filled with 0
10-
var matrix = [[Int]](count:self.characters.count+1, repeatedValue:[Int](count:other.characters.count+1, repeatedValue:0))
11-
12-
for (i, selfChar) in self.characters.enumerate() {
13-
for (j, otherChar) in other.characters.enumerate() {
14-
if (otherChar == selfChar) {
15-
//Common char found, add 1 to highest lcs found so far
16-
matrix[i+1][j+1] = (matrix[i][j]) + 1
17-
}
18-
else {
19-
//Not a match, propagates highest lcs length found so far
20-
matrix[i+1][j+1] = max(matrix[i][j+1], matrix[i+1][j])
21-
}
22-
}
23-
}
24-
25-
//Due to propagation, lcs length is at matrix[n][m]
26-
return matrix;
2+
public func longestCommonSubsequence(other: String) -> String {
3+
4+
// Computes the length of the lcs using dynamic programming.
5+
// Output is a matrix of size (n+1)x(m+1), where matrix[x][y] is the length
6+
// of lcs between substring (0, x-1) of self and substring (0, y-1) of other.
7+
func lcsLength(other: String) -> [[Int]] {
8+
9+
// Create matrix of size (n+1)x(m+1). The algorithm needs first row and
10+
// first column to be filled with 0.
11+
var matrix = [[Int]](count: self.characters.count+1, repeatedValue: [Int](count: other.characters.count+1, repeatedValue: 0))
12+
13+
for (i, selfChar) in self.characters.enumerate() {
14+
for (j, otherChar) in other.characters.enumerate() {
15+
if otherChar == selfChar {
16+
// Common char found, add 1 to highest lcs found so far.
17+
matrix[i+1][j+1] = matrix[i][j] + 1
18+
} else {
19+
// Not a match, propagates highest lcs length found so far.
20+
matrix[i+1][j+1] = max(matrix[i][j+1], matrix[i+1][j])
21+
}
2722
}
28-
29-
//Backtracks from matrix[n][m] to matrix[1][1] looking for chars that are common to both strings
30-
func backtrack(matrix: [[Int]]) -> String {
31-
var i = self.characters.count
32-
var j = other.characters.count
33-
34-
//charInSequence is in sync with i so we can get self[i]
35-
var charInSequence = self.endIndex
36-
37-
var lcs = String()
38-
39-
while (i >= 1 && j >= 1) {
40-
//Indicates propagation without change, i.e. no new char was added to lcs
41-
if (matrix[i][j] == matrix[i][j - 1]) {
42-
j = j - 1
43-
}
44-
//Indicates propagation without change, i.e. no new char was added to lcs
45-
else if (matrix[i][j] == matrix[i - 1][j]) {
46-
i = i - 1
47-
//As i was subtracted, move back charInSequence
48-
charInSequence = charInSequence.predecessor()
49-
}
50-
//Value on the left and above are different than current cell. This means 1 was added to lcs length (line 16)
51-
else {
52-
i = i - 1
53-
j = j - 1
54-
charInSequence = charInSequence.predecessor()
55-
56-
lcs.append(self[charInSequence])
57-
}
58-
}
59-
60-
//Due to backtrack, chars were added in reverse order: reverse it back.
61-
//Append and reverse is faster than inserting at index 0
62-
return String(lcs.characters.reverse());
23+
}
24+
25+
// Due to propagation, lcs length is at matrix[n][m].
26+
return matrix
27+
}
28+
29+
// Backtracks from matrix[n][m] to matrix[1][1] looking for chars that are
30+
// common to both strings.
31+
func backtrack(matrix: [[Int]]) -> String {
32+
var i = self.characters.count
33+
var j = other.characters.count
34+
35+
// charInSequence is in sync with i so we can get self[i]
36+
var charInSequence = self.endIndex
37+
38+
var lcs = String()
39+
40+
while i >= 1 && j >= 1 {
41+
// Indicates propagation without change: no new char was added to lcs.
42+
if matrix[i][j] == matrix[i][j - 1] {
43+
j -= 1
44+
}
45+
// Indicates propagation without change: no new char was added to lcs.
46+
else if matrix[i][j] == matrix[i - 1][j] {
47+
i -= 1
48+
// As i was decremented, move back charInSequence.
49+
charInSequence = charInSequence.predecessor()
50+
}
51+
// Value on the left and above are different than current cell.
52+
// This means 1 was added to lcs length (line 17).
53+
else {
54+
i -= 1
55+
j -= 1
56+
charInSequence = charInSequence.predecessor()
57+
lcs.append(self[charInSequence])
6358
}
64-
65-
//Combine dynamic programming approach with backtrack to find the lcs
66-
return backtrack(lcsLength(other))
59+
}
60+
61+
// Due to backtrack, chars were added in reverse order: reverse it back.
62+
// Append and reverse is faster than inserting at index 0.
63+
return String(lcs.characters.reverse())
6764
}
68-
}
65+
66+
// Combine dynamic programming approach with backtrack to find the lcs.
67+
return backtrack(lcsLength(other))
68+
}
69+
}

0 commit comments

Comments
 (0)