簡體   English   中英

創建按總和排序的所有可能組合

[英]Creating all possible combinations sorted by sum

給定一組任意數字S = {1..n}和大小k ,我需要打印按總和排序的大小k所有可能組合。

假設S = {1, 2, 3, 4, 5}k = 3 ,示例輸出將是:

1 2 3 = 6
1 2 4 = 7
1 2 5 = 8
1 3 4 = 8
1 3 5 = 9
2 3 4 = 9
2 3 5 = 10
1 4 5 = 10
2 4 5 = 11
3 4 5 = 12

我想到的第一個想法是對S進行排序(如果尚未排序),然后執行 BFS 搜索,將組合隊列按總和排序。 這是因為我只想在請求時生成下一個組合(類似迭代器)。 但這似乎有點矯枉過正,我認為應該有一個更簡單的解決方案。 如何解決這個問題?

編輯:

這是我最初的想法:

1. Sort S
2. Pick the first k numbers and add them to the queue as a single node (because this is the combination with the smallest sum)
3. While the queue is not empty - pop the first node, output it, and generate successors.

Generating successors:
1. Start with the first number in the node. Make a copy of a node. Find the smallest unselected value that is > than the number, and assign this value.
2. Verify that this node hasn't been seen and calculate the sum.
3. Add the node to the queue.
4. Repeat 1-3 for all of the remaining numbers in the node.

例子:

Queue q = { {1, 2, 3} = 6 }
Pop front, output
    1 2 3 = 6
Generate {4, 2, 3} = 9, {1, 4, 3} = 8, {1, 2, 4} = 7
Seen { {1, 2, 3}, {4, 2, 3}, {1, 4, 3}, {1, 2, 4} }

Queue q = { {1, 2, 4} = 7, {1, 4, 3} = 8, {4, 2, 3} = 9 }
Pop front, output
    1 2 3 = 6
    1 2 4 = 7
Generate {3, 2, 4} = 9 (seen - discard), {1, 3, 4} = 8 (seen - discard), {1, 2, 5} = 8 }
Seen { {1, 2, 3}, {4, 2, 3}, {1, 4, 3}, {1, 2, 4}, {1, 2, 5} }

Queue q = { {1, 2, 5} = 8, {1, 4, 3} = 8, {4, 2, 3} = 9 }
Pop front, output
    1 2 3 = 6
    1 2 4 = 7
    1 2 5 = 8
Generate {3, 2, 5} = 10, {1, 3, 5} = 9
Seen { {1, 2, 3}, {4, 2, 3}, {1, 4, 3}, {1, 2, 4}, {1, 2, 5}, {3, 2, 5}, {1, 3, 5} }

Queue q = { {1, 4, 3} = 8, {1, 5, 3} = 9, {1, 3, 5} = 9,  {3, 2, 5} = 10, {1, 4, 5} = 10, {4, 2, 5} = 11 }
...
...

如下所示的 javascript 示例;

<!DOCTYPE html> 

<html>  
   <head> 
      <meta charset = utf-8> 
      <title>s{1..n} by k</title> 
   </head> 
  
   <body> 
      <header>s{1..n} by k</header> 
      <form action="#" onsubmit="return false;">
s:<input type="text" id="sArrayObj" name="sArrayObj" value="4 5 1 8 9 3 6 7"/><br/>
n:<input type="text" id="kVarObj" name="kVarObj" value="3"/><br/>
<button id="scan" name="scan" onclick="scanX()"> CALCULATE </button><br/>
<textarea id="scanned" name="scanned"  cols=40 rows=20>
</textarea>   
        </form>
      <script>
        const headFactorial = n => {
          if ( n > 1 ) return n * headFactorial( n - 1 );
          else return 1;
        }

        const tailFactorial = n => {
          if ( n === 1 ) return 1;
          else return n * tailFactorial( n - 1 );
        }

        const combinations = ( collection, combinationLength ) => {
          let head, tail, result = [];
          if ( combinationLength > collection.length || combinationLength < 1 ) { return []; }
          if ( combinationLength === collection.length ) { return [ collection ]; }
          if ( combinationLength === 1 ) { return collection.map( element => [ element ] ); }
          for ( let i = 0; i < collection.length - combinationLength + 1; i++ ) {
            head = collection.slice( i, i + 1 );
            tail = combinations( collection.slice( i + 1 ), combinationLength - 1 );
            for ( let j = 0; j < tail.length; j++ ) { result.push( head.concat( tail[ j ] ) ); }
          }
          return result;
        }
        
        const sumArr = (anArr) => {
            var s=0;
            for (j=0; j < anArr.length; j++) s += 1*anArr[j];
            return s;
        }
        
        function scanX(){
            sArray = document.getElementById("sArrayObj").value.split(" ");
            kVar = document.getElementById("kVarObj").value;
            sArray.sort();
            resultObj= document.getElementById("scanned");
            resultObj.value = "";
            //for (i=0;kVar > i;i++){
            //  resultObj.value+=sArray[i]+' ';
            //}
            resultArr = combinations(sArray, kVar);
            for (i=0;i<resultArr.length;i++){
                resultObj.value += resultArr[i]+"="+sumArr(resultArr[i])+"\n";
            }
            
            return false;
        }
      </script>
    </body> 
</html> 

暫無
暫無

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

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