1. 程式人生 > >回溯法求解陣列中和為固定值的所有元素集合

回溯法求解陣列中和為固定值的所有元素集合

一、前言

       本文參考自http://blog.csdn.net/u012462822/article/details/51193689,找出陣列中和為固定值的所有元素集合,常用的思路是先進行排序,之後再用回溯的方法不斷嘗試所有可能集合。以下先用快速排序(寫得有點爛)降序,再找出降了序的陣列中和為某值的所有元素集合

二、回溯法

      程式碼如下

#include <iostream>
#include <stdio.h>
#include <vector>

using namespace std;

void QSort(int * arr,int idxStart,int idxEnd)
{
   if (idxEnd<1||arr == NULL)  return;

   int key = arr[idxStart];

   int i = idxStart ;
   int j = idxEnd;

   while(j != i){
       while(j != i){
           if(arr[j]>key){
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
                i++;
                break;
           }else{
                j--;
       	   }
       }

      while(j != i){
           if( arr[i] <=key){
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
                j--;
                break;
           }else{
                i++;
           }
      }
   }

   if(i > 1){
      QSort(arr,0,i-1);
   }
   if(idxEnd-i > 1){
      QSort(arr,i+1,idxEnd);
   }

}

/*
    arr: 陣列指標
    n: 陣列長度
    beginIdx: 表示搜尋的位置,初始為0
    currSums:存貯搜尋元素的和,初始為0
    findT:固定值
    res:儲存搜尋的元素

*/
void BackTrack( int* arr  , int  n   ,  int beginIdx    ,   int currSums ,  int  findT  , vector< int > & res  )
 {
        if (  beginIdx >= n  ||    currSums > findT )  return; //判斷搜尋是否該結束

        currSums  +=arr[  beginIdx ] ;   //加入下標為beginIdx的元素
        res.push_back( arr[  beginIdx  ] );

        if( currSums ==  findT){   //判斷當前搜尋到的元素是否滿足和為findT,滿足則輸出集合
                for(int i = 0 ; i <  res.size(); ++i)
                        cout<< res[i]  <<"   ";
                        cout<<"\n";
        }

        BackTrack(    arr ,  n   , beginIdx+1 ,  currSums  ,    findT  ,   res     ) ;  //嘗試找下一個
        res .pop_back();          //如果BackTrack發生return,說明如果加入beginIdx處的元素不滿足要求
        currSums  -=arr[  beginIdx ] ;

        int j ;

        for(   j = beginIdx+1 ;  j <  n ;  ){  //跳過beginIdx之後可能相同的元素
                if(  arr[j] ==arr[  beginIdx ]  ){
                        j++;
                }else{
                        break;
                }

        }

        BackTrack(  arr ,  n    ,  j ,     currSums    ,    findT     ,   res); //在J後重新搜尋

 }


int main()
{

        int  arr[] = { 6 , 202 , 88,  -102 ,   100 , 41,  12  ,  23 ,   34  ,  25 ,  50, 41 , 11 };
        int n =  13 ;

        QSort(    arr    ,    0 ,     n -1 );
        cout<<"排序後\n";
        for(int i = 0 ; i < n ; ++i){
                cout<<  arr[i] <<  "  "  ;
        }

        vector< int >  path ;
        int findT = 100;
        int beginIdx = 0;
        int currSums = 0;

        cout<<"\n\n和為" <<findT<<"的元素集合為:\n";
        BackTrack(   arr    , n   ,   beginIdx    ,   currSums ,   findT  , path  ) ;

}


三、執行結果