簡體   English   中英

如何找到總和等於函數出現次數的數字?

[英]how to find numbers whose sum is equal to the number of occurrences of the function?

在輸入函數上,我們不對數字數組進行排序,也不采用通過將給定數組中的數字相加而獲得的數字。

必須返回找到的第一個數字,該數字的總和等於從函數參數獲得的數字。

我幾乎設法獲得了所需的東西,但是由於附加了條件,我陷入了陷阱,現在我無法從零中減去負數,而又不加上另一個會否使第二個數變為正數的觀點,因此您可以從零中減去,然后再將其轉換回去。

(在第二個函數調用中,當我們從-6中減去0時,我設法僅在最后一個循環中才將0和-6相加)

如何從零中減去數字並減少邏輯?

 function sum_pairs(ints, s){ let arr=[]; for(let i=0; i<ints.length; i++){ for(let j=1; j<ints.length; j++){ if(s>=0){ if(ints[i]+ints[j] === s){ arr.push(ints[i], ints[j]); return arr } } else{ /* if(ints[i] === 0 ){ ints[j] = Math.abs(ints[j]) } */ if(ints[i]-ints[j] === s){ arr.push(ints[i], ints[j]); return arr } } } } } console.log(sum_pairs([1, 4, 8, 7, 3, 15], 8)) // [1,7] console.log(sum_pairs([1, -2, 3, 0, -6, 1], -6)) // [0,-6] console.log(sum_pairs([10, 5, 2, 3, 7, 5], 10)) // [3,7] 

如何從零中減去數字?

  0 - someNumber

並減少邏輯?

1)不需要arr ,只需返回數組文字即可。

2)您不需要if / else來區分否定/肯定結果, 0 + (-6)-6因此不需要if / else。

3)您不需要元素索引,因此只需進行迭代即可將其清理干凈。

 function sumPairs(nums, expected) {
   for(const a of nums) {
     for(const b of nums) {
       if(a + b === expected) {
          return [a, b];
       }
     }
   }
 }

代數

如何從零中減去數字並減少邏輯?

正如@Jonas Wilms提到的,在另一個數字B上加上負數A將導致從B中減去 A。

let A = 1
let B = -6
A + B
// <- -5
// because (1 + -6) => (1 - 6) = -5

因此,您可以完全刪除if(s>=0){

算法

您想從ints求和為sum的第一對數字。

從原理上來說,迭代ints是正確的,然后再次進行迭代以找到匹配的數字。

修復1:始終返回正確的對

問題

原始算法有時會返回假對。 舉個例子

sum_pairs([10, 5, 2, 3, 7, 1], 10))

這將錯誤地返回[5,5]

s = 10
i = 1
j = 1
ints[i] + ints[j] === s // true because ints[1] = 5

確保您永遠不要在相同的數組索引處添加數字。

我們通過添加

if (j === i) continue;

 function sumPairsSimple(ints, sum) { for (let i = 0; i < ints.length; i++) { for (let j = 0; j < ints.length; j++) { if (j === i) continue; if (ints[i] + ints[j] === sum) { return [ints[i], ints[j]] } } } } console.log(sumPairsSimple([1, 4, 8, 7, 3, 15], 8)) // [1,7] console.log(sumPairsSimple([1, -2, 3, 0, -6, 1], -6)) // [0,-6] console.log(sumPairsSimple([10, 5, 2, 3, 7, 1], 10)) // [3,7] 

還要注意,我返回的是數組文字,以保持代碼整潔,簡短和易於閱讀。

修復2:優化

第二個解決方案是優化。 請注意,兩個for循環都從0開始並遍歷所有ints

問題

讓我們假設以下調用:

sum_pairs([5, 4, 8, 10], 18)

結果是增加了以下內容:

ints[0] + ints[1]
ints[0] + ints[2]
ints[0] + ints[3]

ints[1] + ints[0] // same as ints[0] + ints[1]
ints[1] + ints[2]
ints[1] + ints[3]

ints[2] + ints[0] // same as ints[0] + ints[2]
ints[2] + ints[1] // same as ints[1] + ints[2]
ints[2] + ints[3]

如您在上面的代碼中所看到的,有很多冗余。

在這一步中,我們將刪除這些冗余並贏得一些CPU周期:)

我們將只檢查當前元素之后的元素,因為我們知道我們已經在其前面

ints[0] + ints[1]
ints[0] + ints[2]
ints[0] + ints[3]

ints[1] + ints[2]
ints[1] + ints[3]

ints[2] + ints[3]

這為我們節省了3個冗余計算。

在代碼中,我們通過從j = i + 1開始內部循環來實現:

 function sumPairsOptimized(ints, sum) { for(let i=0; i<ints.length; i++) { for(let j=i+1; j<ints.length; j++) { if(ints[i] + ints[j] === sum) { return [ints[i], ints[j]] } } } } console.log(sumPairsOptimized([1, 4, 8, 7, 3, 15], 8)) // [1,7] console.log(sumPairsOptimized([1, -2, 3, 0, -6, 1], -6)) // [0,-6] console.log(sumPairsOptimized([10, 5, 2, 3, 7, 1], 10)) // [3,7] 

如果只需要第一個匹配結果,建議使用Array.someArray.find的組合。

 function findSummands(numbers, equalTo) { let summands = [] numbers.some(lhs => numbers.find(rhs => { if (lhs + rhs === equalTo) { summands.push(lhs, rhs) return true } return false })) return summands } const test1 = findSummands([1, 4, 8, 7, 3, 15], 8) const test2 = findSummands([1, -2, 3, 0, -6, 1], -6) const test3 = findSummands([10, 5, 2, 3, 7, 5], 10) console.log({test1, test2, test3}) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM