Task: Levenshtein distance


C++: #include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>
 
template <typename StringType>
size_t levenshtein_distance(const StringType& s1, const StringType& s2) {
    const size_t m = s1.size();
    const size_t n = s2.size();
    if (m == 0)
        return n;
    if (n == 0)
        return m;
    std::vector<size_t> costs(n + 1);
    std::iota(costs.begin(), costs.end(), 0);
    size_t i = 0;
    for (auto c1 : s1) {
        costs[0] = i + 1;
        size_t corner = i;
        size_t j = 0;
        for (auto c2 : s2) {
            size_t upper = costs[j + 1];
            costs[j + 1] = (c1 == c2) ? corner
                : 1 + std::min(std::min(upper, corner), costs[j]);
            corner = upper;
            ++j;
        }
        ++i;
    }
    return costs[n];
}
 
int main() {
    std::wstring s0 = L"rosettacode";
    std::wstring s1 = L"raisethysword";
    std::wcout << L"distance between " << s0 << L" and " << s1 << L": "
        << levenshtein_distance(s0, s1) << std::endl;
    return 0;
}








COBOL:        identification division.
       program-id. Levenshtein.
 
       environment division.
       configuration section.
       repository.
           function all intrinsic.
 
       data division.
       working-storage section.
       77  string-a               pic x(255).
       77  string-b               pic x(255).
       77  length-a               pic 9(3).
       77  length-b               pic 9(3).
       77  distance               pic z(3).
       77  i                      pic 9(3).
       77  j                      pic 9(3).
       01  tab.
           05 filler              occurs 256.
              10 filler           occurs 256.
                 15 costs         pic 9(3).

       procedure division.
       main.
           move "kitten" to string-a
           move "sitting" to string-b
           perform levenshtein-dist

           move "rosettacode" to string-a
           move "raisethysword" to string-b
           perform levenshtein-dist
           stop run
           .
       levenshtein-dist.
           move length(trim(string-a)) to length-a
           move length(trim(string-b)) to length-b

           initialize tab
           
           perform varying i from 0 by 1 until i > length-a
              move i to costs(i + 1, 1)
           end-perform

           perform varying j from 0 by 1 until j > length-b
              move j to costs(1, j + 1)
           end-perform
           
           perform with test after varying i from 2 by 1 until i > length-a
              perform with test after varying j from 2 by 1 until j > length-b
                 if string-a(i - 1:1) = string-b(j - 1:1)
                    move costs(i - 1, j - 1) to costs(i, j)
                 else
                    move min(min(costs(i - 1, j) + 1,     
                                 costs(i, j - 1) + 1),    
                             costs(i - 1, j - 1) + 1)     
                       to costs(i, j)
                 end-if
              end-perform
           end-perform
           move costs(length-a + 1, length-b + 1) to distance
           display trim(string-a) " -> " trim(string-b) " = " trim(distance)
           .