test_class.declarator: comp
test_class.modifier: private
test_class.original_string: private PersonNameComparator comp;
test_class.type: PersonNameComparator
test_class.var_name: comp
test_class.file: lib/Duke/duke-core/src/test/java/no/priv/garshol/duke/comparators/PersonNameComparatorTest.java
test_class.identifier: PersonNameComparatorTest
test_case.body: @Test
    public void testEditDistance() {
      assertEquals(0.95, comp.compare("lars marius garshol", "lars marus garshol"));
      assertEquals(0.95, comp.compare("lars marus garshol", "lars marius garshol"));
    }
test_case.class_method_signature: PersonNameComparatorTest.testEditDistance()
test_case.full_signature: @Test public void testEditDistance()
test_case.identifier: testEditDistance
test_case.invocations: assertEquals compare assertEquals compare
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testEditDistance()
focal_class.file: lib/Duke/duke-core/src/main/java/no/priv/garshol/duke/comparators/PersonNameComparator.java
focal_class.identifier: PersonNameComparator
focal_class.interfaces: implements Comparator
focal_class.class_method_signature: PersonNameComparator.isTokenized()
focal_class.full_signature: @Override public boolean isTokenized()
focal_class.identifier: isTokenized
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: boolean
focal_class.signature: boolean isTokenized()
focal_class.class_method_signature: PersonNameComparator.compare(String v1, String v2)
focal_class.full_signature: @Override public double compare(String v1, String v2)
focal_class.identifier: compare
focal_class.modifiers: @Override public
focal_class.parameters: (String v1, String v2)
focal_class.return: double
focal_class.signature: double compare(String v1, String v2)
focal_method.body: @Override
  public double compare(String v1, String v2) {
      if (v1.equals(v2))
        return 1.0;
  
      if (v1.length() + v2.length() > 20 && Levenshtein.distance(v1, v2) == 1)
        return 0.95;
      
      String[] t1 = StringUtils.split(v1);
      String[] t2 = StringUtils.split(v2);
  
      // t1 must always be the longest
      if (t1.length < t2.length) {
        String[] tmp = t2;
        t2 = t1;
        t1 = tmp;
      }    
  
      // penalty imposed by pre-processing
      double penalty = 0;
      
      // if the two are of unequal lengths, make some simple checks
      if (t1.length != t2.length && t2.length >= 2) {
        // is the first token in t1 an initial? if so, get rid of it
        if ((t1[0].length() == 2 && t1[0].charAt(1) == '.') ||
            t1[0].length() == 1) {
          String[] tmp = new String[t1.length - 1];
          for (int ix = 1; ix < t1.length; ix++)
            tmp[ix - 1] = t1[ix];
          t1 = tmp;
          penalty = 0.2; // impose a penalty
        } else {
          // use similarity between first and last tokens, ignoring what's
          // in between
          int d1 = Levenshtein.distance(t1[0], t2[0]);
          int d2 = Levenshtein.distance(t1[t1.length - 1], t2[t2.length - 1]);
          return (0.4 / (d1 + 1)) + (0.4 / (d2 + 1));
        }
      }
  
      // if the two are of the same length, go through and compare one by one
      if (t1.length == t2.length) {
        // are the names just reversed?
        if (t1.length == 2 && t1[0].equals(t2[1]) && t1[1].equals(t2[0]))
          return 0.9;
  
        // normal one-by-one comparison
        double points = 1.0 - penalty;
        for (int ix = 0; ix < t1.length && points > 0; ix++) {
          int d = Levenshtein.distance(t1[ix], t2[ix]);
          
          if (ix == 0 && d > 0 &&
              (t1[ix].startsWith(t2[ix]) || t2[ix].startsWith(t1[ix]))) {
            // are we at the first name, and one is a prefix of the other?
            // if so, we treat this as edit distance 1
            d = 1;
          } else if (d > 1 && (ix + 1) <= t1.length) {
            // is it an initial? ie: "marius" ~ "m." or "marius" ~ "m"
            String s1 = t1[ix];
            String s2 = t2[ix];
            // ensure s1 is the longer
            if (s1.length() < s2.length()) {
              String tmp = s1;
              s1 = s2;
              s2 = tmp;
            }
            if ((s2.length() == 2 && s2.charAt(1) == '.') ||
                s2.length() == 1) {
              // so, s2 is an initial
              if (s2.charAt(0) == s1.charAt(0))
                d = 1; // initial matches token in other name
            }
          } else if (t1[ix].length() + t2[ix].length() <= 4)
            // it's not an initial, so if the strings are 4 characters
            // or less, we quadruple the edit dist
            d = d * 4;
          else if (t1[ix].length() + t2[ix].length() <= 6)
            // it's not an initial, so if the strings are 3 characters
            // or less, we triple the edit dist
            d = d * 3;
          else if (t1[ix].length() + t2[ix].length() <= 8)
            // it's not an initial, so if the strings are 4 characters
            // or less, we double the edit dist
            d = d * 2;
          
          points -= d * 0.1;
        }
  
        // if both are just one token, be strict
        if (t1.length == 1 && points < 0.8)
          return 0.0;
        
        return Math.max(points, 0.0);
      }
      
      return 0.0;
    }
focal_method.class_method_signature: PersonNameComparator.compare(String v1, String v2)
focal_method.full_signature: @Override public double compare(String v1, String v2)
focal_method.identifier: compare
focal_method.invocations: equals length length distance split split length charAt length distance distance equals equals distance startsWith startsWith length length length charAt length charAt charAt length length length length length length max
focal_method.modifiers: @Override public
focal_method.parameters: (String v1, String v2)
focal_method.return: double
focal_method.signature: double compare(String v1, String v2)