zoukankan      html  css  js  c++  java
  • [C++] 递归之全排列问题、半数集

    一、递归的定义

      一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个原问题相似的规模较小的问题来求解。

    二、用递归求解问题的主要步骤

      1、找出相似性

      2、定义出口

    三、递归实例

      1、全排列问题

      例如:

      list[3] = {1,2,3}。

      则全排列结果为:{1,2,3},{1,3,2},{2,1,3},{2,3,1},{3,2,1},{3,1,2}。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 void Perm(int list[], int k, int m);
     5 void Swap(int &a, int &b);
     6 
     7 void Perm(int list[], int k, int m)
     8 {//产生list[k:m]的所有排列 
     9     if(k == m)
    10     {    //只剩下1个元素 
    11         for(int i = 0; i <= m; i++)
    12             cout<< list[i];
    13         cout<<endl;
    14     }
    15     else    //还有多个元素待排列,递归产生排列 
    16         for(int i = k; i <= m; i++)
    17         {
    18                 Swap(list[k], list[i]);
    19                 Perm(list, k+1, m);
    20                 Swap(list[k], list[i]);
    21         }
    22 }
    23 
    24 void Swap(int &a, int &b)
    25 {
    26     int temp = a; a = b; b = temp;
    27 }
    28 
    29 int main()
    30 {
    31     int list[3] = {1,2,3};
    32     Perm(list, 0, 2);    
    33     return 0;
    34 }

      2、重复元素全排列

      例如:

      list[4] = {1,1,2,2}。

      则重复元素全排列结果为:{1,1,2,2},{1,2,1,2},{1,2,2,1},{2,1,1,2},{2,1,2,1},{2,2,1,1}。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 void Perm(int list[], int k, int m);
     5 void Swap(int &a, int &b);
     6 bool ok(int list[], int k, int i);
     7 
     8 void Perm(int list[], int k, int m)
     9 {//产生list[k:m]的所有排列 
    10     if(k == m)
    11     {    //只剩下1个元素 
    12         for(int i = 0; i <= m; i++)
    13             cout<< list[i];
    14         cout<<endl;
    15     }
    16     else    //还有多个元素待排列,递归产生排列 
    17         for(int i = k; i <= m; i++)
    18         {    //若不重复则执行 
    19             if(ok(list, k, i))
    20             {
    21                 Swap(list[k], list[i]);
    22                 Perm(list, k+1, m);
    23                 Swap(list[k], list[i]);
    24             }
    25         }
    26 }
    27 
    28 void Swap(int &a, int &b)
    29 {
    30     int temp = a; a = b; b = temp;
    31 }
    32 
    33 //判断元素[k..i-1]与i是否重复 
    34 bool ok(int list[], int k, int i)
    35 {
    36     if(i > k)
    37     {
    38         for(int t = k; t < i; t++)
    39         {
    40             if(list[t] == list[i])
    41                 return false;
    42         }
    43     }
    44     else
    45         return true;
    46 }
    47 
    48 int main()
    49 {
    50     int list[4] = {1,1,2,2};
    51     Perm(list, 0, 3);    
    52     return 0;
    53 }

      3、半数集

      在自然数 n 的左边加上一个自然数,但该自然数不能超过最近添加的数的一半。

      set(6) = {6,16,26,126,36,136},半数集 set(n) 的元素个数。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 //递归算法 
     5 int comp(int n)
     6 {
     7     int ans = 1;
     8     if(n > 1)
     9     {
    10         for(int i = 1; i <= n/2; i++)
    11             ans += comp(i);
    12     }
    13     return ans;
    14 }
    15 
    16 /*
    17 记忆式搜索方法
    18 该方法用数组 a 来记录已经算过的半数集元素个数,
    19 当输入的n在之前计算过时,则直接输出a[n]即可 
    20 */
    21 int a[1001];
    22 int comp2(int n)
    23 {
    24     int ans = 1;
    25     if(a[n] > 0)
    26         return a[n];
    27         
    28     for(int i = 1; i <= n/2; i++)
    29         ans += comp2(i);
    30     a[n] = ans;
    31     return ans;
    32 }
    33 
    34 int main()
    35 {
    36     int n;
    37     cin>> n;
    38     int ans = comp(n);
    39     cout<< ans <<endl;
    40     
    41     int ans2 = comp2(n);
    42     cout<< ans2 <<endl;
    43     return 0;
    44 }
  • 相关阅读:
    小程序 循环遍历 传参数 获取参数的方法
    小程序技巧 盒子布局
    小程序的初体验
    python制作网易云免费下载器
    数据结构实验报告之三元组顺序存储的稀疏矩阵练习(代码版)
    JavaFX作业8
    用JavaFX显示一个转动的风扇
    用JavaFX模拟一个交通信号灯
    数据结构作业周三必交
    大数据的就业观与考研观
  • 原文地址:https://www.cnblogs.com/cao-lei/p/6891308.html
Copyright © 2011-2022 走看看