code: private static int _getDistance (@Nonnull final char [] aStr1,
                                     @Nonnegative final int nLen1,
                                     @Nonnull final char [] aStr2,
                                     @Nonnegative final int nLen2,
                                     @Nonnegative final int nCostInsert,
                                     @Nonnegative final int nCostDelete,
                                     @Nonnegative final int nCostSubstitution)
    {
      // previous cost array, horizontally
      int [] aPrevRow = new int [nLen1 + 1];
  
      // cost array, horizontally
      int [] aCurRow = new int [nLen1 + 1];
  
      // init
      for (int i = 0; i <= nLen1; i++)
        aPrevRow[i] = i * nCostInsert;
  
      for (int j = 0; j < nLen2; j++)
      {
        final int ch2 = aStr2[j];
        aCurRow[0] = (j + 1) * nCostDelete;
  
        for (int i = 0; i < nLen1; i++)
        {
          final int nSubstCost = aStr1[i] == ch2 ? 0 : nCostSubstitution;
          aCurRow[i + 1] = Math.min (Math.min (aCurRow[i] + nCostInsert, aPrevRow[i + 1] + nCostDelete),
                                     aPrevRow[i] + nSubstCost);
        }
  
        // swap current distance counts to 'previous row' distance counts
        final int [] tmp = aPrevRow;
        aPrevRow = aCurRow;
        aCurRow = tmp;
      }
  
      // our last action in the above loop was to switch d and p, so p now
      // actually has the most recent cost counts
      return aPrevRow[nLen1];
    }
docs: Main generic Levenshtein implementation. Assume all preconditions are
  checked.
  
  @param aStr1
  Not null
  @param nLen1
  &gt; 0
  @param aStr2
  Not null
  @param nLen2
  &gt; 0
  @param nCostInsert
  &ge; 0
  @param nCostDelete
  &ge; 0
  @param nCostSubstitution
  &ge; 0
  @return non negative distance