diff options
author | Kaelyn Uhrain <rikka@google.com> | 2012-02-15 22:13:07 +0000 |
---|---|---|
committer | Kaelyn Uhrain <rikka@google.com> | 2012-02-15 22:13:07 +0000 |
commit | 01d53ec176a6be4585df1f43af11151988ca4b35 (patch) | |
tree | 9476d14ac77e1cce9d7c01620eb476f2a8170117 /lib/Support | |
parent | 68c36e0c26d6abc6e19ac66a24061d8c4a187767 (diff) |
Add function for computing the edit distance of two arrays.
Accomplished by moving the body of StringRef::edit_distance into
a separate function that accepts two ArrayRefs, and making
StringRef::edit_distance a wrapper around the new function.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150621 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r-- | lib/Support/StringRef.cpp | 56 |
1 files changed, 5 insertions, 51 deletions
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp index e73c6e38e2..4d20903e84 100644 --- a/lib/Support/StringRef.cpp +++ b/lib/Support/StringRef.cpp @@ -10,6 +10,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/edit_distance.h" #include <bitset> using namespace llvm; @@ -84,57 +85,10 @@ int StringRef::compare_numeric(StringRef RHS) const { unsigned StringRef::edit_distance(llvm::StringRef Other, bool AllowReplacements, unsigned MaxEditDistance) { - // The algorithm implemented below is the "classic" - // dynamic-programming algorithm for computing the Levenshtein - // distance, which is described here: - // - // http://en.wikipedia.org/wiki/Levenshtein_distance - // - // Although the algorithm is typically described using an m x n - // array, only two rows are used at a time, so this implemenation - // just keeps two separate vectors for those two rows. - size_type m = size(); - size_type n = Other.size(); - - const unsigned SmallBufferSize = 64; - unsigned SmallBuffer[SmallBufferSize]; - llvm::OwningArrayPtr<unsigned> Allocated; - unsigned *previous = SmallBuffer; - if (2*(n + 1) > SmallBufferSize) { - previous = new unsigned [2*(n+1)]; - Allocated.reset(previous); - } - unsigned *current = previous + (n + 1); - - for (unsigned i = 0; i <= n; ++i) - previous[i] = i; - - for (size_type y = 1; y <= m; ++y) { - current[0] = y; - unsigned BestThisRow = current[0]; - - for (size_type x = 1; x <= n; ++x) { - if (AllowReplacements) { - current[x] = min(previous[x-1] + ((*this)[y-1] == Other[x-1]? 0u:1u), - min(current[x-1], previous[x])+1); - } - else { - if ((*this)[y-1] == Other[x-1]) current[x] = previous[x-1]; - else current[x] = min(current[x-1], previous[x]) + 1; - } - BestThisRow = min(BestThisRow, current[x]); - } - - if (MaxEditDistance && BestThisRow > MaxEditDistance) - return MaxEditDistance + 1; - - unsigned *tmp = current; - current = previous; - previous = tmp; - } - - unsigned Result = previous[n]; - return Result; + return llvm::ComputeEditDistance( + llvm::ArrayRef<char>(data(), size()), + llvm::ArrayRef<char>(Other.data(), Other.size()), + AllowReplacements, MaxEditDistance); } //===----------------------------------------------------------------------===// |