2011-02-22 5 views
0

최근에 this question에 최적의 단어 줄 바꿈을위한 함수를 생성하고이 Python 스크립트에서 찾고있는 응답을 받았습니다. 불행히도, 저는 파이썬을 말하지 않습니다. : D 누군가 이것을 Objective-C로 변환하도록 도울 수 있습니까?Python 스크립트를 Objective-C로 변환

는 _

Code. I took the liberty of modifying the DP always to return exactly n lines, at the  cost of increasing the running time from O(#words ** 2) to O(#words ** 2 * n). 

def minragged(text, n=3): 
    """ 
    >>> minragged('Just testing to see how this works.') 
    ['Just testing', 'to see how', 'this works.'] 
    >>> minragged('Just testing to see how this works.', 10) 
    ['', '', 'Just', 'testing', 'to', 'see', 'how', 'this', 'works.', ''] 
    """ 
    words = text.split() 
    cumwordwidth = [0] 
    # cumwordwidth[-1] is the last element 
    for word in words: 
     cumwordwidth.append(cumwordwidth[-1] + len(word)) 
    totalwidth = cumwordwidth[-1] + len(words) - 1 # len(words) - 1 spaces 
    linewidth = float(totalwidth - (n - 1))/float(n) # n - 1 line breaks 
    def cost(i, j): 
     """ 
     cost of a line words[i], ..., words[j - 1] (words[i:j]) 
     """ 
     actuallinewidth = max(j - i - 1, 0) + (cumwordwidth[j] - cumwordwidth[i]) 
     return (linewidth - float(actuallinewidth)) ** 2 
    # best[l][k][0] is the min total cost for words 0, ..., k - 1 on l lines 
    # best[l][k][1] is a minimizing index for the start of the last line 
    best = [[(0.0, None)] + [(float('inf'), None)] * len(words)] 
    # xrange(upper) is the interval 0, 1, ..., upper - 1 
    for l in xrange(1, n + 1): 
     best.append([]) 
     for j in xrange(len(words) + 1): 
      best[l].append(min((best[l - 1][k][0] + cost(k, j), k) for k in xrange(j + 1))) 
    lines = [] 
    b = len(words) 
    # xrange(upper, 0, -1) is the interval upper, upper - 1, ..., 1 
    for l in xrange(n, 0, -1): 
     a = best[l][b][1] 
     lines.append(' '.join(words[a:b])) 
     b = a 
    lines.reverse() 
    return lines 

if __name__ == '__main__': 
    import doctest 
    doctest.testmod() 
+3

모든 들여 쓰기를 수행했습니다. 들여 쓰기는 파이썬의 문법의 일부입니다. 중괄호로 묶는 대신에 들여 쓰기를하십시오. – slezica

+0

질문을 편집하고 코드의 형식을 올바르게 지정하십시오 (또는 작성한 사람에게 들여 쓰기 버전을 제공하도록 요청하십시오). 들여 쓰기가없는 파이썬 코드를 읽는 것은 불가능합니다. 이는 C 코드에서'{'와'}를 모두 제거하는 것과 같습니다. – ThiefMaster

+0

Yikes! 깨닫지 못 했어. 원래 코드는 여기에 게시됩니다 : http://stackoverflow.com/questions/5059956/algorithm-to-divide-text-into-3-evenly-sized-groups –

답변

1

여기 오브젝티브 C로 변환하는 기능이다. 컴파일을 위해 업데이트되었지만 정확성 만 테스트했습니다 (예제에서는 previous question : [... minragged:@"Just testing to see how this works." lineCount:3]). 효율성이나 목적 -C 관용구에 관한 어떤 것도 고려되지 않았습니다.

@interface NSMutableArray (reverse) 
/* Could also return self, but this makes it explicit that array is reversed in-place 
    rather than returning a reversed copy. 
*/ 
-(void)reverse; 
@end 

@implementation NSMutableArray (reverse) 
-(void)reverse { 
    int i,j; 
    for (i=0,j=[self count]-1; i<j; ++i,--j) { 
     [self exchangeObjectAtIndex:i withObjectAtIndex:j]; 
    } 
} 
@end 




-(NSArray*)minragged:(NSString*)text lineCount:(int)n { 
    int width = 0; 
    NSArray *words = [text componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    NSMutableArray *cumWordWidth = [NSMutableArray arrayWithObject:[NSNumber numberWithInt:width]]; 
    for (NSString *word in words) { 
     width += [word length]; 
     [cumWordWidth addObject:[NSNumber numberWithInt:width]]; 
    } 
    int totalWidth = width + [words count] - 1, 
     lineWidth = (double)(totalWidth - (n - 1))/(double)(n), 
     actualLineWidth, 
     i, j, k, min_k; 
    double cost, min_cost; 

    // best[i][k][0] is the min total cost for words 0, ..., k - 1 on i lines 
    // best[i][k][1] is a minimizing index for the start of the last line 
    NSMutableArray *best = [NSMutableArray arrayWithCapacity:n], 
        *best_i_prev = [NSMutableArray arrayWithCapacity:([words count]+1)], 
        *best_i; 

    [best_i_prev addObject:[NSArray arrayWithObjects:[NSNumber numberWithDouble:0.0],[NSNull null],nil]]; 
    for (i=0; i < [words count]; ++i) { 
     [best_i_prev addObject:[NSArray arrayWithObjects:(NSNumber*)kCFNumberPositiveInfinity,[NSNull null],nil]]; 
    } 
    [best addObject:best_i_prev]; 

    for (i=1; i <= n; ++i) { 
     best_i=[NSMutableArray arrayWithCapacity:[words count]]; 
     for (j=0; j <= [words count]; ++j) { 
      min_k=0; 
      min_cost = [(NSNumber*)kCFNumberPositiveInfinity doubleValue]; 
      for (k=0; k < j; ++k) { 
       actualLineWidth = j - k - 1; 
       if (actualLineWidth < 0) { 
        actualLineWidth = 0; 
       } 
       actualLineWidth += [[cumWordWidth objectAtIndex:j] intValue] 
            - [[cumWordWidth objectAtIndex:k] intValue]; 
       cost = (lineWidth - (double)(actualLineWidth)); 
       cost *= cost; 
       cost += [[[best_i_prev objectAtIndex:k] objectAtIndex:0] doubleValue]; 
       if (cost < min_cost) { 
        min_cost = cost; 
        min_k = k; 
       } 
      } 
      [best_i addObject:[NSArray arrayWithObjects:[NSNumber numberWithDouble:min_cost], 
                 [NSNumber numberWithInt:min_k], 
                 nil]]; 
     } 
     [best addObject:best_i]; 
     best_i_prev = best_i; 
    } 

    NSMutableArray *lines = [NSMutableArray arrayWithCapacity:n]; 
    NSRange range; 
    int end; 
    end = [words count]; 
    for (i=n; i > 0; --i) { 
     range.location = [[[[best objectAtIndex:i] objectAtIndex:end] objectAtIndex:1] intValue]; 
     range.length = end-range.location; 
     [lines addObject:[[words subarrayWithRange:range] componentsJoinedByString:@" "]]; 
     end = range.location; 
    } 
    [lines reverse]; 
    return lines; 
} 

당신은 너무로 메모리를 소모하지 -minragged:lineCount:에서 만든 객체를 취소 오토 릴리즈 풀을 생성 할 수 있습니다. 그럴 경우 풀을 배수하기 전에 lines을 유지하고 나중에 자동 수거하십시오.

+0

아직 작동하지 않지만 확실히 가까워지고 있습니다. 오류없이 실행되도록 약간의 수정을했습니다 (반환 된 응답은 정확하지 않습니다). 누군가가 내 편집 내용을 승인 해 주길 바랍니다. –

+0

@Brian : 테스트 할 샘플이 하나 뿐이지 만 컴파일을하기에는 너무 게을러 웠지만 (이 대답에 대한 내 운영자의 말) 다른 사람들을 만드는 데는 @Brian : 귀하의 수정 사항을 승인했지만 SO가 대기 중이라고 표시하지 않았습니다. – outis

+0

작동하지 않습니다! 고맙습니다! 고맙습니다! –

관련 문제