Skip to content

Commit 4a0eca2

Browse files
Valdas3Valdas
and
Valdas
authored
Add Levenshtein Distance (#336)
Co-authored-by: Valdas <valdas771@gmail.com>
1 parent 5831b7d commit 4a0eca2

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Algorithms.Strings;
2+
using NUnit.Framework;
3+
4+
namespace Algorithms.Tests.Strings
5+
{
6+
public class LevenshteinDistanceTests
7+
{
8+
[Test]
9+
[TestCase("kitten", "sitting", 3)]
10+
[TestCase("bob", "bond", 2)]
11+
[TestCase("algorithm", "logarithm", 3)]
12+
[TestCase("star", "", 4)]
13+
[TestCase("", "star", 4)]
14+
[TestCase("abcde", "12345", 5)]
15+
public void Calculate_ReturnsCorrectLevenshteinDistance(string source, string destination, int expectedDistance)
16+
{
17+
var result = LevenshteinDistance.Calculate(source, destination);
18+
Assert.AreEqual(expectedDistance, result);
19+
}
20+
}
21+
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System;
2+
3+
namespace Algorithms.Strings
4+
{
5+
/// <summary>
6+
/// <para>
7+
/// Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or substitutions) required to change one word into the other.
8+
/// </para>
9+
/// <para>
10+
/// Wikipedia: https://en.wikipedia.org/wiki/Levenshtein_distance.
11+
/// </para>
12+
/// </summary>
13+
public static class LevenshteinDistance
14+
{
15+
/// <summary>
16+
/// Calculates Levenshtein distance.
17+
/// Time and space complexity is O(ab) where a and b are the lengths of the source and target strings.
18+
/// </summary>
19+
/// <param name="source">Source string.</param>
20+
/// <param name="target">Target string.</param>
21+
/// <returns>Levenshtein distance between source and target strings.</returns>
22+
public static int Calculate(string source, string target)
23+
{
24+
var distances = new int[source.Length + 1, target.Length + 1];
25+
26+
for(var i = 0; i <= source.Length; i++)
27+
{
28+
distances[i, 0] = i;
29+
}
30+
31+
for (var i = 0; i <= target.Length; i++)
32+
{
33+
distances[0, i] = i;
34+
}
35+
36+
for (var i = 1; i <= source.Length; i++)
37+
{
38+
for (var j = 1; j <= target.Length; j++)
39+
{
40+
var substitionCost = source[i - 1] == target[j - 1] ? 0 : 1;
41+
distances[i, j] = Math.Min(distances[i - 1, j] + 1, Math.Min(distances[i, j - 1] + 1, distances[i - 1, j - 1] + substitionCost));
42+
}
43+
}
44+
45+
return distances[source.Length, target.Length];
46+
}
47+
}
48+
}

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ find more than one implementation for the same objective but using different alg
158158
* [Boyer Moore](./Algorithms/Strings/BoyerMoore.cs)
159159
* [Palindrome Checker](./Algorithms/Strings/Palindrome.cs)
160160
* [Get all permutations of a string](./Algorithms/Strings/Permutation.cs)
161+
* [Levenshtein Distance](./Algorithms/Strings/LevenshteinDistance.cs)
161162
* [Other](./Algorithms/Other)
162163
* [Fermat Prime Checker](./Algorithms/Other/FermatPrimeChecker.cs)
163164
* [Sieve of Eratosthenes](./Algorithms/Other/SieveOfEratosthenes.cs)

0 commit comments

Comments
 (0)