欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言中遞歸和排列組合詳解

 更新時間:2022年01月13日 10:08:04   作者:布布要成為最強的人  
大家好,本篇文章主要講的是C語言中遞歸和排列組合詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽

排列組合三大問題:

1.打印n個數(shù)的全排列
2.打印n個數(shù)中任意m個數(shù)的全排列
3.打印n個數(shù)中任意m個數(shù)的組合

1.打印n個數(shù)的全排列

這個題實際上是可以直接用STL中的next_permutation()函數(shù),代碼如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
	int data[4]={5,2,4,1};
	sort(data,data+4);//先排序得到字典序最小的序列
	do{
		for(int i=0;i<4;i++)
			cout<<data[i]<<" ";
		cout<<endl;
	}while(next_permutation(data,data+4));
}
這樣輸出出來的全排列是按照字典序輸出的,這是它的優(yōu)點。

如果用遞歸求全排列呢?
假如給了n個數(shù)123…n,求其全排列的數(shù)量,應當如何解決呢,下面給出一個遞歸的思路:

一開始先按照字典序排列,然后把第一個數(shù)依次和后面的數(shù)交換:
1 2 3 4 5…n
2 1 3 4 5…n
.
.
.
n 2 3 4 5…1
這是第一層遞歸,只要第一個數(shù)不同,不需要管后面n-1個數(shù)

然后在上面的每個數(shù)列中去掉第一個數(shù),對后面的n-1個數(shù)做如上操作,例如取第二組做該操作,則該第二層的遞歸為:
1 3 4 5…n
3 1 4 5…n
.
.
.
n 3 4 5…1

重復以上步驟,直到用完所有的數(shù)字。

這么講并不好理解,我從小規(guī)模到大規(guī)模來闡述這個思想:

假如只有兩個數(shù)1,2需要進行全排列工作:
先按字典序排成1,2,這是第一層遞歸的第一組
把1去掉,只留下一個數(shù),那么只有1種情況。
第一層遞歸的第二組是2,1,這也是最后一組了
把2去掉,只留下一個數(shù),那么只有1種情況
因此兩個數(shù)的全排列是兩種情況

假如有三個數(shù)1,2,3需要進行全排列工作:
直接看第一層遞歸的三種情況:
1、2、3;2、1、3;3、2、1
每一種情況都把第一個數(shù)去掉,就變成只有2個數(shù)的全排列了
而由上述所知,兩個數(shù)的全排列有兩種情況
那么第一層遞歸的三種情況都各自包含兩種情況即3×2=6

往后依舊借用前面的標準即可。
可是放到代碼實現(xiàn)的時候可不能做完一層刪一個數(shù),只能實現(xiàn)的了保留那層遞歸的第一個數(shù),然后繼續(xù)對下面的數(shù)做遞歸操作,這樣就完美符合了遞歸的思想。
代碼實現(xiàn)如下:

#include<bits/stdc++.h>
using namespace std;
#define Swap(a,b){int temp=a;a=b;b=temp;}
//也可以用STL的swap函數(shù),但是速度慢一些
int data[]={1,2,3,4,5};
int num=0;
void Perm(int begin,int end){
    if(begin==end)num++;//遞歸到底了,自然只有一種情況,num++
    else{
        for(int i=begin;i<=end;i++){
        	//i要注意從begin開始,自己和自己換的也算是一種情況
            Swap(data[begin],data[i]);
            Perm(begin+1,end);//保留第一個數(shù),進入下一層遞歸
            Swap(data[begin],data[i]);//要記得換回來
        }
    }
}
int main(){
	Perm(0,4);
	cout<<num<<endl;
}

如果想要輸出這個排列,直接在Perm函數(shù)中的if語句下面做循環(huán)輸出即可。
需要注意的是:這樣輸出出來的并不一定符合字典序。

2.打印n個數(shù)中任意m個數(shù)的全排列

這個只需要把上面if語句中的條件改一下就行,改成begin==m即可
思路是一樣的,從小規(guī)模列起就好了。

3.打印n個數(shù)中任意m個數(shù)的組合

這個和上面的第2個問題就不一樣了,組合問題只需要選m個數(shù)而無須做排列,應該怎么實現(xiàn)呢?
利用二進制的思想,原理如下:
設一個集合{a0,a1,a2,…,an-1},子集共有2的n次方個,其中包括空集。
例如一個n=3的集合{a0,a1,a2},其子集為{φ},{a0},{a1},{a1,a0},{a2},{a2,a0},{a2,a1},{a2,a1,a0}。為什么以這個順序來排呢?因為這樣非常符合二進制位權值的思想。剛好可以和二進制對應:

φa0a1a1 a0a2a2 a0a2 a1a2 a1 a0
000001010011100101110111

如何輸出這些子集?,還是利用二進制位權的思想,利用相與運算得出其二進制數(shù)中的每一個1,直接對應數(shù)字,完全代碼如下:

#include<bits/stdc++.h>
using namespace std;
void print_subset(int n){
    for(int i=0;i<(1<<n);i++){
        for(int j=0;j<n;j++)//打印子集,即打印i的二進制數(shù)中的每一個1
            if(i&(1<<j))
                cout<<j<<" ";
        cout<<endl;
    }
}
int main(){
	int n;
	cin>>n;
	print_subset(n);
}

回到問題3,要找到任意m個數(shù)的組合,只需要做一個判斷:確定一個子集對應的二進制數(shù)中1的數(shù)量。這是解題的關鍵。
有一個很巧妙的做法:kk=kk&(kk-1)
重復使用該式子,直到kk為0,即可得出1的數(shù)量。

完整代碼如下:

#include<bits/stdc++.h>
using namespace std;
void print_subset(int n,int k){
    for(int i=0;i<(1<<n);i++){
        int num=0,kk=i;
        while(kk){
            kk=kk&(kk-1);
            num++;
        }
        if(num==k){
            for(int j=0;j<n;j++)//打印子集,即打印i的二進制數(shù)中的每一個1
                if(i&(1<<j))
                    cout<<j<<" ";
            cout<<endl;
        }
    }
}
int main(){
	int n,k;
	cin>>n>>k;
	print_subset(n,k);
}

總結

到此這篇關于C語言中遞歸和排列組合詳解的文章就介紹到這了,更多相關C語言遞歸和排列組合內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C 語言程序結構示例解析

    C 語言程序結構示例解析

    本文主要講解C 語言程序結構,這里提供簡單的示例來講解C 語言程序的結構,有利于剛剛學習C 語言的同學理解程序結構
    2016-08-08
  • C語言?超詳細講解鏈接器

    C語言?超詳細講解鏈接器

    在C語言中,一個重要的思想就是分別編譯,即若干個源程序能夠在不一樣的時候單獨進行編譯,而后在恰當?shù)臅r候整合到一塊兒??墒擎溄悠魍ǔJ桥cC編譯器分離的,鏈接器如何作到把若干個C源程序合并成一個總體呢,我們一起來看看
    2022-03-03
  • C++ 智能指針的模擬實現(xiàn)實例

    C++ 智能指針的模擬實現(xiàn)實例

    這篇文章主要介紹了C++ 智能指針的模擬實現(xiàn)實例的相關資料,智能指針是一個類,它把普通指針封裝起來,能實現(xiàn)和普通指針同樣的功能。,需要的朋友可以參考下
    2017-07-07
  • 深入C/C++浮點數(shù)在內存中的存儲方式詳解

    深入C/C++浮點數(shù)在內存中的存儲方式詳解

    本篇文章是對C/C++浮點數(shù)在內存中的存儲方式進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解C++調用Python腳本中的函數(shù)的實例代碼

    詳解C++調用Python腳本中的函數(shù)的實例代碼

    這篇文章主要介紹了C++調用Python腳本中的函數(shù) ,需要的朋友可以參考下
    2018-11-11
  • C語言中堆空間的生成與釋放詳解

    C語言中堆空間的生成與釋放詳解

    以下是對C語言中堆空間的生成與釋放進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • mfc入門教程之通過控制變量制作計算器

    mfc入門教程之通過控制變量制作計算器

    這篇文章主要介紹了mfc入門教程之通過控制變量制作計算器,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • C/C++ 中extern關鍵字詳解

    C/C++ 中extern關鍵字詳解

    這篇文章主要介紹了C/C++ 中extern關鍵字詳解的相關資料,需要的朋友可以參考下
    2017-06-06
  • C語言實現(xiàn)個人財務管理軟件

    C語言實現(xiàn)個人財務管理軟件

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)個人財務管理軟件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • VisualStudio2022不支持.NET Framework 4.0項目解決辦法

    VisualStudio2022不支持.NET Framework 4.0項目解決辦法

    本文主要介紹了VisualStudio2022不支持.NET Framework 4.0項目解決辦法,文中通過圖文的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09

最新評論