string-hamming-normalized.js

  1. // wink-distance
  2. // Distance functions for Bag of Words, Strings,
  3. // Vectors and more.
  4. //
  5. // Copyright (C) GRAYPE Systems Private Limited
  6. //
  7. // This file is part of “wink-distance”.
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining a
  10. // copy of this software and associated documentation files (the "Software"),
  11. // to deal in the Software without restriction, including without limitation
  12. // the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13. // and/or sell copies of the Software, and to permit persons to whom the
  14. // Software is furnished to do so, subject to the following conditions:
  15. //
  16. // The above copyright notice and this permission notice shall be included
  17. // in all copies or substantial portions of the Software.
  18. //
  19. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25. // DEALINGS IN THE SOFTWARE.
  26. // ## string
  27. // ### hammingNormalized
  28. /**
  29. *
  30. * Computes the normalized hamming distance between two strings. These strings
  31. * may be of different lengths. Normalized distance is always between 0 and 1.
  32. *
  33. * @method string.hammingNormalized
  34. * @param {string} str1 first string.
  35. * @param {string} str2 second string.
  36. * @return {number} normalized hamming distance between `str1` and `str2`.
  37. * @example
  38. * hammingNormalized( 'john', 'johny' );
  39. * // -> 0.2
  40. * hammingNormalized( 'sam', 'sam' );
  41. * // -> 0
  42. * hammingNormalized( 'sam', 'samuel' );
  43. * // -> 0.5
  44. * hammingNormalized( 'saturn', 'urn' );
  45. * // -> 1
  46. */
  47. var hammingNormalized = function ( str1, str2 ) {
  48. // As we may need to swap values!
  49. var s1 = str1,
  50. s2 = str2;
  51. // String lengths.
  52. var s1Length = s1.length,
  53. s2Length = s2.length;
  54. // Absolute distance between `s1` & `s2`.
  55. var distance;
  56. // Helper variables.
  57. var i, imax;
  58. var dividend;
  59. // Initialize stuff and may have to swap `s1`/`s2`.
  60. if ( s1Length < s2Length ) {
  61. // Swap `s1` and `s2` values.
  62. s1 = [ s2, s2 = s1 ][ 0 ];
  63. // Initialize distance as the difference in lengths of `s1` & `s2`.
  64. distance = s2Length - s1Length;
  65. imax = s1Length;
  66. // Initialize dividend by the larger string length.
  67. dividend = s2Length;
  68. } else {
  69. // No need to swap, but do initialize stuff.
  70. distance = s1Length - s2Length;
  71. imax = s2Length;
  72. dividend = s1Length;
  73. }
  74. // Compute distance.
  75. for ( i = 0; i < imax; i += 1 ) {
  76. if ( s1[ i ] !== s2[ i ] ) distance += 1;
  77. }
  78. // Normalize the distance & return.
  79. return ( dividend ) ? ( distance / dividend ) : 0;
  80. }; // hammingNormalized()
  81. module.exports = hammingNormalized;