龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

C语言实现的排列组合问题的通用算法、解决方法(2)

时间:2014-08-30 02:24来源:网络整理 作者:网络 点击:
分享到:
order[k]++; // 在当前位置选择新的数字 if(order[k] == n) // 当前位置已无数字可选,回溯 { order[k--] = 0; continue; } if(k m) // 更新当前位置的下一位置的数字 { orde

  order[k]++;                // 在当前位置选择新的数字
  if(order[k] == n)          // 当前位置已无数字可选,回溯
  {
   order[k--] = 0;
   continue;
  }    
 
  if(k < m)                  // 更新当前位置的下一位置的数字         
  {
   order[++k] = order[k-1];
   continue;
  }
 
  if(k == m)
   flag = true;
 }

 delete[] order;
 return count;
}


下面是测试以上函数的程序:
复制代码 代码如下:

int main()
{
 const int N = 4;
 const int M = 3;
 int a[N];
 for(int i=0;i<N;i++)
  a[i] = i+1;

 // 回溯方法
 cout << combine(a,N,3) << endl;

 // 递归方法
 int b[M];
 combine(a,N,M,b,M);

 return 0;
}


由上述分析可知,解决组合问题的通用算法不外乎递归和回溯两种。在针对具体问题的时候,因为递归程序在递归层数上的限制,对于大型组合问题而言,递归不是一个好的选择,这种情况下只能采取回溯的方法来解决。

n个数的全排列问题相对简单,可以通过交换位置按序枚举来实现。STL提供了求某个序列下一个排列的算法next_permutation,其算法原理如下:
1. 从当前序列最尾端开始往前寻找两个相邻元素,令前面一个元素为*i,后一个元素为*ii,且满足*i<*ii;

2. 再次从当前序列末端开始向前扫描,找出第一个大于*i的元素,令为*j(j可能等于ii),将i,j元素对调;

3. 将ii之后(含ii)的所有元素颠倒次序,这样所得的排列即为当前序列的下一个排列。

其实现代码如下:

复制代码 代码如下:

template <class BidirectionalIterator>
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last)
{
  if (first == last) return false;   // 空範圍
  BidirectionalIterator i = first;
  ++i;
  if (i == last) return false;       // 只有一個元素
  i = last;                          // i 指向尾端
  --i;

 for(;;)
 {
  BidirectionalIterator ii = i;
  --i;
  // 以上,鎖定一組(兩個)相鄰元素
  if (*i < *ii)                     // 如果前一個元素小於後一個元素
  {
   BidirectionalIterator j = last;  // 令 j指向尾端
   while (!(*i < *--j));            // 由尾端往前找,直到遇上比 *i 大的元素
   iter_swap(i, j);                 // 交換 i, j
   reverse(ii, last);               // 將 ii 之後的元素全部逆向重排
   return true;
  }
  if (i == first)                   // 進行至最前面了
  {
   reverse(first, last);            // 全部逆向重排
   return false;
  }
 }
}


下面程序演示了利用next_permutation来求取某个序列全排列的方法:
复制代码 代码如下:

int main()
{
 int ia[] = {1,2,3,4};
 vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));

精彩图集

赞助商链接