2010-03-07 5 views

답변

12

(자본 "T"는 "I"하나의 "시간"과 누락 된 공간 일) 당신 ' 찾고있는 것은 Levenshtein Distance입니다.

목표 - C에서 구현 :

위의 소스의
------------------------------------------------------------------------ 

// 
// NSString-Levenshtein.h 
// 
// Created by Rick Bourner on Sat Aug 09 2003. 
// [email protected] 

@interface NSString(Levenshtein) 

// calculate the smallest distance between all words in stringA and stringB 
- (float) compareWithString: (NSString *) stringB; 

// calculate the distance between two string treating them each as a 
// single word 
- (float) compareWithWord: (NSString *) stringB; 

// return the minimum of a, b and c 
- (int) smallestOf: (int) a andOf: (int) b andOf: (int) c; 

@end 

-------------------------------------------------------------------- 

// 
// NSString-Levenshtein.m 
// 
// Created by Rick Bourner on Sat Aug 09 2003. 
// [email protected] 

#import "NSString-Levenshtein.h" 


@implementation NSString(Levenshtein) 

// calculate the mean distance between all words in stringA and stringB 
- (float) compareWithString: (NSString *) stringB 
{ 
    float averageSmallestDistance = 0.0; 
    float smallestDistance; 
    float distance; 

    NSMutableString * mStringA = [[NSMutableString alloc] initWithString: self]; 
    NSMutableString * mStringB = [[NSMutableString alloc] initWithString: stringB]; 


    // normalize 
    [mStringA replaceOccurrencesOfString:@"\n" 
           withString: @" " 
           options: NSLiteralSearch 
            range: NSMakeRange(0, [mStringA length])]; 

    [mStringB replaceOccurrencesOfString:@"\n" 
           withString: @" " 
           options: NSLiteralSearch 
            range: NSMakeRange(0, [mStringB length])]; 

    NSArray * arrayA = [mStringA componentsSeparatedByString: @" "]; 
    NSArray * arrayB = [mStringB componentsSeparatedByString: @" "]; 

    NSEnumerator * emuA = [arrayA objectEnumerator]; 
    NSEnumerator * emuB; 

    NSString * tokenA = NULL; 
    NSString * tokenB = NULL; 

    // O(n*m) but is there another way ?!? 
    while (tokenA = [emuA nextObject]) { 

     emuB = [arrayB objectEnumerator]; 
     smallestDistance = 99999999.0; 

     while (tokenB = [emuB nextObject]) 
      if ((distance = [tokenA compareWithWord: tokenB]) < smallestDistance) 
       smallestDistance = distance; 

     averageSmallestDistance += smallestDistance; 

    } 

    [mStringA release]; 
    [mStringB release]; 

    return averageSmallestDistance/[arrayA count]; 
} 


// calculate the distance between two string treating them eash as a 
// single word 
- (float) compareWithWord: (NSString *) stringB 
{ 
    // normalize strings 
    NSString * stringA = [NSString stringWithString: self]; 
    [stringA stringByTrimmingCharactersInSet: 
       [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    [stringB stringByTrimmingCharactersInSet: 
       [NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    stringA = [stringA lowercaseString]; 
    stringB = [stringB lowercaseString]; 


    // Step 1 
    int k, i, j, cost, * d, distance; 

    int n = [stringA length]; 
    int m = [stringB length]; 

    if(n++ != 0 && m++ != 0) { 

     d = malloc(sizeof(int) * m * n); 

     // Step 2 
     for(k = 0; k < n; k++) 
      d[k] = k; 

     for(k = 0; k < m; k++) 
      d[ k * n ] = k; 

     // Step 3 and 4 
     for(i = 1; i < n; i++) 
      for(j = 1; j < m; j++) { 

       // Step 5 
       if([stringA characterAtIndex: i-1] == 
         [stringB characterAtIndex: j-1]) 
        cost = 0; 
       else 
        cost = 1; 

       // Step 6 
       d[ j * n + i ] = [self smallestOf: d [ (j - 1) * n + i ] + 1 
              andOf: d[ j * n + i - 1 ] + 1 
              andOf: d[ (j - 1) * n + i -1 ] + cost ]; 
      } 

     distance = d[ n * m - 1 ]; 

     free(d); 

     return distance; 
    } 
    return 0.0; 
} 


// return the minimum of a, b and c 
- (int) smallestOf: (int) a andOf: (int) b andOf: (int) c 
{ 
    int min = a; 
    if (b < min) 
     min = b; 

    if(c < min) 
     min = c; 

    return min; 
} 

@end 

저자 : 릭 Bourner, http://www.merriampark.com/ldobjc.htm

+0

좋은! 그러면 정확히 어떻게 작동 시키나요? –

+0

나는 가장 희한한 생각이 없다! 내가 Objective-C 코드를 게시 한 이유는 (1) 당신이 작업하고있는 언어라고 생각했기 때문이며 (2) 코드가'merriampark.com '에서 나온 것이기 때문에 (IMHO) 신뢰할 수있는 소스가되었습니다. 개인적으로, 나는 iPhone 애플 리케이션이 작성된 언어에 대한 경험이 없습니다. 그러나 알고리즘과 의사 코드는 그 순간에 작업 할 수 있도록 충분히 제공해야합니다. 맞습니까? –

+3

이것은 NSString의 카테고리이므로 적절한 헤더 및 구현 파일에이 파일을 넣은 다음 헤더를 포함하면 [string1 compareWithString : string1] 할 수 있어야합니다. –

관련 문제