Skip to content

Commit 3231815

Browse files
authored
Merge pull request #4 from qedsoftware/fix-ops
Fix ops; Add new tests that check transform using ops
2 parents f36e492 + ca0b7b4 commit 3231815

3 files changed

Lines changed: 57 additions & 2 deletions

File tree

editdistance/_edit_distance_osa.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,15 @@ std::vector<std::vector<CppEditop>> backtrack_all_paths(
7777
const double tol = 1e-6;
7878

7979
if (i > 0 && std::abs((dp[i-1][j] + delete_weight) - current_cost) < tol) {
80-
CppEditop op(DELETE, i-1, i-1, delete_weight, std::string(1, a[i-1]));
80+
CppEditop op(DELETE, i-1, j, delete_weight, std::string(1, a[i-1]));
8181
current_path.push_back(op);
8282
auto paths = backtrack_all_paths(a, b, dp, i-1, j, current_path, replace_weight, insert_weight, delete_weight, swap_weight);
8383
all_paths.insert(all_paths.end(), paths.begin(), paths.end());
8484
current_path.pop_back();
8585
}
8686

8787
if (j > 0 && std::abs((dp[i][j-1] + insert_weight) - current_cost) < tol) {
88-
CppEditop op(INSERT, i, i, insert_weight, std::string(1, b[j-1]));
88+
CppEditop op(INSERT, i, j-1, insert_weight, std::string(1, b[j-1]));
8989
current_path.push_back(op);
9090
auto paths = backtrack_all_paths(a, b, dp, i, j-1, current_path, replace_weight, insert_weight, delete_weight, swap_weight);
9191
all_paths.insert(all_paths.end(), paths.begin(), paths.end());

editdistance/edit_distance_osa.pyx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,29 @@ def get_all_paths(
9898
python_paths.append(python_path)
9999
return python_paths
100100

101+
def apply_editops(src, dst, editops):
102+
src_idx = 0
103+
s = ""
104+
for op in editops:
105+
while src_idx < op.src_idx:
106+
s += src[src_idx]
107+
src_idx += 1
108+
if op.name == EditopName.INSERT:
109+
s += dst[op.dst_idx]
110+
elif op.name == EditopName.DELETE:
111+
src_idx += 1
112+
elif op.name == EditopName.REPLACE:
113+
s += dst[op.dst_idx]
114+
src_idx += 1
115+
elif op.name == EditopName.SWAP:
116+
s += src[op.src_idx + 1]
117+
s += src[op.src_idx]
118+
src_idx += 2
119+
while src_idx < len(src):
120+
s += src[src_idx]
121+
src_idx += 1
122+
return s
123+
101124

102125
def print_all_paths(
103126
str a,

tests/tests_osa.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22

33
from editdistance.osa import (
4+
apply_editops,
45
compute_distance,
56
get_all_paths,
67
)
@@ -22,6 +23,28 @@
2223
("entirely different", "cab", "axb", 2),
2324
]
2425

26+
EDITOPS_TRANSFORM_TEST_CASES = [
27+
("abc", "acb"),
28+
("kitten", "sitting"),
29+
("flaw", "lawn"),
30+
("", "abc"),
31+
("abc", ""),
32+
("abcdef", "azced"),
33+
("a", "a"),
34+
("a", ""),
35+
("", ""),
36+
("banana", "ban"),
37+
("intention", "execution"),
38+
("gumbo", "gambol"),
39+
("sunday", "saturday"),
40+
("ca", "abc"),
41+
("abcdef", "fedcba"),
42+
("racecar", "racecar"),
43+
("spelling", "spilling"),
44+
("distance", "instance"),
45+
("book", "back"),
46+
]
47+
2548

2649
class TestOsaDistance(unittest.TestCase):
2750
def test_compute_distance(self):
@@ -49,3 +72,12 @@ def test_get_all_paths(self):
4972
):
5073
paths = get_all_paths(source, target)
5174
self.assertEqual(len(paths), expected_num_paths)
75+
76+
def test_editops_transform(self):
77+
for src, dst in EDITOPS_TRANSFORM_TEST_CASES:
78+
with self.subTest(src=src, dst=dst):
79+
paths = get_all_paths(src, dst)
80+
self.assertTrue(paths, f"No paths found for {src} -> {dst}")
81+
for path in paths:
82+
result = apply_editops(src, dst, path)
83+
self.assertEqual(result, dst, f"Failed for {src} -> {dst} with path {path}")

0 commit comments

Comments
 (0)