2014-11-11 5 views
1

대상 번호와 값 배열이있는 경우 대상 값까지 합한 모든 숫자 조합을 어떻게 찾을 수 있습니까?배열에서 지정된 값을 더하는 모든 값을 찾습니다.

target_number = 42 
sample_values = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28] 

여기에 대한 답변은 다음과 같습니다 내가 검색이 유형에 대한 mathmatical 용어, 당신을 위해 그것을 할 가능성이 루비 라이브러리가 확신

14 + 28 = 42 
13 + 27 = 42 
12 + 26 = 42 
... 
1 + 13 + 28 = 42 
2 + 12 + 28 = 42 
... 

.

중첩 된 for 루프없이 어떻게 할 수 있습니까?

sample_values.each do | x | 
    sample_values.each do | i | 
    sample_values.each do | j | 
     if x + i + j == target_number 
     puts "#{x} + #{i} + #{j} is #{target_number}" 
     end 
    end 
    end 
end 

답변

3

이것은 Subset Sum 문제입니다.

Ruby combination 방법도 확인하십시오.

할 수있는 빠른 방법이 될 것이다 : 각각의

a = [1,2,3,4,5] 
arr = [] 
numOfCombinations = 0 

for i in 0..(a.length) do 
    a.combination(i).each do |b| 
    c = b.reduce(:+) 
     if c == target_number 
     numOfCombinations += 1 
     end 
    end 
end 

note: this is slow with a large number array

+0

감사하지만, 아무 것도 반환하지 않습니다. 이유가 확실하지 않습니다. http://rubyfiddle.com/riddles/c1dde/2 – spuder

+0

@spuder 작성된 코드는 아무 것도 반환하지 않습니다. 주석에 표시된대로, 당신은'if' 문 안에서 카운터를 증가시킬 것으로 예상됩니다. 그러나'if '는 대상 번호를 항상 false 인 숫자 배열과 비교하기 때문에 작성된대로 작동하지 않습니다. 대신 배열의 숫자 합계와 비교해야합니다. –

+0

Fyi를 사용하면 조합을 배열로 변환 할 필요가 없습니다. 사실, 그렇지 않을 수도 있습니다. 또한 대상 번호와 비교하기 전에'.reduce (: +)'와 합산하는 것을 잊어 버렸습니다. – Ajedi32

1
target_number = 42 
sample_values = (1..28).to_a 

(1..sample_values.length). 
    map { |length| sample_values.combination(length).to_a. 
    select { |candidate| candidate.reduce(:+) == target_number } 
    }.flatten(1) 

sample_values의 길이를 1에서 숫자의 범위에서 코드 반복을 생성하는 모든 조합 길이를 계산 한 다음 target_number에 합한 조합 만 필터링 한 다음 결과에서 중첩 수준을 하나 제거합니다.

1에서 28까지의 숫자 집합에서이 작업을 수행하려면 길이가 시간이 걸립니다. 예를 변경하여 1에서 20까지의 숫자 만 사용하면 몇 초 안에 결과가 나타납니다.

=> [[3, 19, 20], [4, 18, 20], [5, 17, 20], [5, 18, 19], [6, 16, 20], [6, 17, 19], [7, 15, 20], [7, 16, 19], [7, 17, 18], [8, 14, 20], [8, 15, 19], [8, 16, 18], [9, 13, 20], [9, 14, 19], [9, 15, 18], [9, 16, 17], [10, 12, 20], [10, 13, 19], [10, 14, 18], [10, 15, 17], [11, 12, 19], [11, 13, 18], [11, 14, 17], [11, 15, 16], [12, 13, 17], [12, 14, 16], [13, 14, 15], [1, 2, 19, 20], [1, 3, 18, 20], [1, 4, 17, 20], [1, 4, 18, 19], [1, 5, 16, 20], [1, 5, 17, 19], [1, 6, 15, 20], [1, 6, 16, 19], [1, 6, 17, 18], [1, 7, 14, 20], [1, 7, 15, 19], ... 
+0

와우, 네 말이 맞아, 20에서 28까지는 상당히 오래 걸린다 (아직 끝나지 않았다). 내 실제 데이터 세트에는 200 개의 배열 값이 포함되어 있으며 계산하는 데 수개월이 걸릴 수 있습니다. – spuder

+0

예, 방금 컴퓨터에서 끝났습니다. 이 값을 200 개의 배열 값에 대해 빠르게 처리하려면 또 다른 접근법을 취해야 할 것입니다.이 무차별 대입 접근법은 O (n!)이며 매우 비싸게 빠릅니다. –

+0

사용중인 실제 값 (대상 및 샘플 모두)에 따라 재귀 적 강하 방법이 더 잘 수행 될 수 있습니다. 여기서의 관찰은 무차별 대입 (brute-force) 방법이 합계가 목표보다 큽니다. 합계가 타겟과 일치하는 후보를 찾으면 해당 후보를 접두사로 갖는 조합을 무시할 수 있습니다. 그러나 목표 값이 클 경우 많은 비용을 절약 할 수는 없으며 샘플에 음수 값이 포함 된 경우 전혀 작동하지 않습니다. 흥미로운 질문. 제출해 주셔서 감사합니다. –

관련 문제