Skip to content
This repository was archived by the owner on Apr 23, 2026. It is now read-only.

Commit e97e2d2

Browse files
committed
fix algo and do stuff
1 parent bb87f1e commit e97e2d2

7 files changed

Lines changed: 53 additions & 29 deletions

File tree

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
[package]
2-
name = "lcs"
2+
name = "fast-lcs"
33
version = "0.1.0"
4-
edition = "2021"
4+
edition = "2024"
5+
license = "MIT"
6+
readme = "README.md"
7+
repository = "https://github.com/reflex-dev/lcs"
58

69
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
710
[lib]
8-
name = "lcs"
11+
name = "fast_lcs"
912
crate-type = ["cdylib"]
1013

1114
[dependencies]

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# fast-lcs
2+
3+
```python
4+
from fast_lcs import compute_lcs_similarity
5+
6+
compute_lcs_similarity(source="bab", target="abacaba", length_of_prefixes_of_target=[3, 4])
7+
```

fast_lcs.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
def compute_lcs_similarity(
2+
source: str, target: str, length_of_prefixes_of_target: list[int]
3+
) -> list[float]: ...

lcs.pyi

Lines changed: 0 additions & 1 deletion
This file was deleted.

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ requires = ["maturin>=1.11,<2.0"]
33
build-backend = "maturin"
44

55
[project]
6-
name = "lcs"
7-
requires-python = ">=3.8"
6+
name = "fast-lcs"
7+
description = "A fast implementation of the longest common subsequence."
8+
requires-python = ">=3.13"
89
classifiers = [
910
"Programming Language :: Rust",
1011
"Programming Language :: Python :: Implementation :: CPython",
1112
"Programming Language :: Python :: Implementation :: PyPy",
1213
]
1314
dynamic = ["version"]
15+
license = { text = "MIT" }
16+
readme = "README.md"
17+
1418
[tool.maturin]
1519
features = ["pyo3/extension-module"]

src/lib.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
use pyo3::prelude::*;
22

33
struct LCS {
4-
calculated: Vec<usize>,
4+
length_of_source: usize,
5+
calculated_table: Vec<usize>,
56
}
67

78
impl LCS {
8-
fn from_strings(s1: &str, s2: &str) -> Self {
9-
let mut previous = vec![0; s2.len() + 1];
10-
let mut current = vec![0; s2.len() + 1];
11-
for c1 in s1.chars() {
12-
for (j, c2) in s2.chars().enumerate() {
9+
fn from_strings(source: &str, target: &str) -> Self {
10+
let mut previous = vec![0; target.len() + 1];
11+
let mut current = vec![0; target.len() + 1];
12+
for c1 in source.chars() {
13+
for (j, c2) in target.chars().enumerate() {
1314
if c1 == c2 {
1415
current[j + 1] = previous[j] + 1;
1516
} else {
@@ -19,30 +20,37 @@ impl LCS {
1920
std::mem::swap(&mut previous, &mut current);
2021
}
2122
Self {
22-
calculated: previous,
23+
length_of_source: source.len(),
24+
calculated_table: previous,
2325
}
2426
}
2527

26-
fn normalized_similarity_of_prefix(&self, prefix_length: usize) -> f64 {
27-
if prefix_length == 0 {
28+
fn normalized_similarity_of_prefix(&self, length_of_prefix_of_target: usize) -> f64 {
29+
if length_of_prefix_of_target == 0 {
2830
return 1.0;
2931
}
30-
let lcs_length = self.calculated[prefix_length];
31-
(2.0 * lcs_length as f64) / (prefix_length + self.calculated.len() - 1) as f64
32+
let lcs_length = self.calculated_table[length_of_prefix_of_target];
33+
(2.0 * lcs_length as f64) / (length_of_prefix_of_target + self.length_of_source) as f64
3234
}
3335
}
3436

3537
#[pyfunction]
36-
fn compute_lcs_similarity(s1: &str, s2: &str, queries: Vec<usize>) -> Vec<f64> {
37-
let lcs = LCS::from_strings(s1, s2);
38-
queries
38+
fn compute_lcs_similarity(
39+
source: &str,
40+
target: &str,
41+
length_of_prefixes_of_target: Vec<usize>,
42+
) -> Vec<f64> {
43+
let lcs = LCS::from_strings(source, target);
44+
length_of_prefixes_of_target
3945
.into_iter()
40-
.map(|prefix_length| lcs.normalized_similarity_of_prefix(prefix_length))
46+
.map(|length_of_prefix_of_target| {
47+
lcs.normalized_similarity_of_prefix(length_of_prefix_of_target)
48+
})
4149
.collect()
4250
}
4351

4452
#[pymodule(gil_used = false)]
45-
fn lcs(m: &Bound<'_, PyModule>) -> PyResult<()> {
53+
fn fast_lcs(m: &Bound<'_, PyModule>) -> PyResult<()> {
4654
m.add_function(wrap_pyfunction!(compute_lcs_similarity, m)?)?;
4755
Ok(())
4856
}

0 commit comments

Comments
 (0)