2016-08-27 5 views
0

내가 알고리즘 설계 및 분석 과정을 복용하고있어, 두 합계 문제의 변종이다 프로그래밍 질문이 주어졌다에서 매우 느린 두 합계 솔루션의 변형 :목표 C

입력은의 배열입니다 1 백만개의 정수. 양수 및 음수 모두. 입력 파일에서 x + y = t를 만족하는 고유 한 숫자 x, y가 있도록 [-10000,10000] (포함) 간격의 목표 값 t 수를 계산하십시오.

나는 작은 테스트 케이스에 대해 올바르게 문제를 해결 객관적인 C의 솔루션을 작성했습니다

:

+ (BOOL)pairExistsForSum:(NSInteger)t dictionary:(NSDictionary *)dictionary 
{ 
    __block BOOL exists = NO; 

    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSNumber *x, BOOL *stop) { 

     NSInteger y = t - x.integerValue; 
     NSString *yKey = [NSString stringWithFormat:@"%li", y]; 

     if (y != x.integerValue && dictionary[yKey]) { 
      exists = YES; 
      *stop = YES; 
     } 
    }]; 

    return exists; 
} 

+ (NSInteger)twoSumProblem:(NSArray <NSNumber *> *)array interval:(NSInteger)min max:(NSInteger)max 
{ 
    NSDictionary *dictionary = [self generateDictionaryOfValuesWithNumbersArray:array]; 
    NSInteger uniquePairs = 0; 

    for (NSInteger i = min; i <= max; i++) { 
     uniquePairs += [self pairExistsForSum:i dictionary:dictionary]; 
    } 

    return uniquePairs; 
} 

문제는 pairExistsForSum의 각 반복이 전체를 의미 완료 2 초 이상 조금 걸립니다입니다 프로세스를 완료하는 데 몇 시간이 걸릴 것입니다. 외측 변경 상보 가산

2)를 찾기 위해

1) 입력 정리 및 양 및 음 배열로 그것을 분할하고, 이진 검색을 사용하여 다음

은 I와 같은 몇몇 대안적인 접근을 시도 for 루프는 0 - 10000 범위를 탐색 한 다음 양수와 음 합 값에 대한 가수를 동시에 검색합니다.

아무런 성능도 크게 향상되지 않았으며이 문제를 하위 문제로 분해하지 않고 각 문제를 동시에 실행하지 않았습니다 t 스레드.

import time 
import bisect 

a = [] 
with open('2sum.txt', 'r') as f: 
    for line in f: 
     a.append(int(line.strip())) 
a.sort() 

ret = set() 
for x in a: 
    lower = bisect.bisect_left(a, -10000 - x) 
    upper = bisect.bisect_right(a, 10000 - x) 
    for y in a[lower:upper]: 
     if x != y and x + y not in ret: 
      ret.add(x + y) 
print len(ret) 

이 솔루션은 초 이하의 문제로 실행 :

는 마침내 다음과 같습니다 사람의 파이썬 해결책을 발견했다. 필자는 Python에 익숙하지 않지만 바이너리 검색을 사용하고 있으며 입력 배열의 데이터를 악용하여 속도를 향상시키지 못한다고 생각합니다. 파이썬 코드가 Objective C보다 빨리 실행되기를 기대하지만,이 솔루션들의 차이는 광대합니다.

  1. 내가 성능 등 광대 한 차이를 설명 할이 두 솔루션의 차이에 대해 누락 것이 있습니다 :

    내 질문은 다음과 같습니다?

  2. Objective c에서 상당한 시간 (즉, 한 시간 미만) 동안이 작업을 수행하기 위해 할 수있는 일이 무엇인지 간과 할 수 있습니까?

(누군가가 여기에 같은 질문을했습니다 : Variant of the 2-sum algorithm with a range of sums) 대답은 주어지지 않았으며, 제 생각에는 더 구체적입니다.

감사합니다.

+2

파이썬 버전 번호를 정렬을 직접 등가물을 가지고 있지만 indexOfObject:inSortedRange:options:usingComparator:을보고 같은 값의 비교의 정의를 "학대"에 대해 조금 생각하지 않습니다 추가 할 후보자를 찾으십시오. 이렇게하면 합계가'[-10000, 10000]'범위를 벗어나는 숫자는 테스트하지 않아도됩니다. – Barmar

답변

2

이러한 두 가지 솔루션의 차이점에 대해 내가 누락 된 점이 있습니까?

"거꾸로"문제가 해결되었습니다. 부터까지 시작한 다음 합계를 검색합니다.두 개의 숫자가 포함 된 극단적 인 예를 생각해보십시오. 20000 테스트를 수행하여 합계가 [-100000, 100000] 범위의 가능한 값 중 하나인지 확인합니다.

파이썬 데이터에 의해 제조 할 수 값이 고려되도록 만 실제 톤, X Y 및 선택에 의해 구동된다. 데이터를 정렬함으로써 솔루션은 범위 내 값의 합인 x, y 쌍만 고려할 수 있습니다.

Objective c에서이 작업을 상당한 시간 (즉, 한 시간 미만)에 실행하기 위해 할 수있는 일이 있습니까?

예, 파이썬 솔루션과 동일한 알고리즘을 구현하기 만하면됩니다. 빠른 Google은 bisect 함수와 파이썬 소스의 스펙을 생성합니다. 당신은 쉽게 구현할 수있는 사소한 바이너리 검색임을 알게 될 것입니다. 그러나 속도면에서 표준 Objective-C 방법을 사용하려고 할 수 있습니다. NSArray는 ... 그것은 이진 검색을 사용할 수 있습니다

HTH