国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++】無(wú)重復(fù)數(shù)字全排列(三種方法)和有重復(fù)數(shù)字全排列

這篇具有很好參考價(jià)值的文章主要介紹了【C++】無(wú)重復(fù)數(shù)字全排列(三種方法)和有重復(fù)數(shù)字全排列。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


一、無(wú)重復(fù)數(shù)字排列

1.1 題目描述

?把 1 ~ n 1~n 1n n n n 個(gè)整數(shù)排成一行后隨機(jī)打亂順序,輸出所有可能的次序。

輸入格式:
一個(gè)整數(shù) n n n 1 ≤ n ≤ 9 1≤n≤9 1n9。
輸出格式:
按照從小到大的順序輸出所有方案,每行 1 1 1 個(gè)。
首先,同一行相鄰兩個(gè)數(shù)用一個(gè)空格隔開(kāi)。
其次,對(duì)于兩個(gè)不同的行,對(duì)應(yīng)下標(biāo)的數(shù)一一比較,字典序較小的排在前面。

1.2 用dfs方法

1.2.1 思路分析

?1. 這個(gè)問(wèn)題其實(shí)就是求無(wú)重復(fù)元素的全排列,經(jīng)典的 d f s dfs dfs 題。 d f s dfs dfs 最重要的是搜索順序,用什么順序遍歷所有方案。對(duì)于全排列問(wèn)題,以 n = 3 n = 3 n=3 為例,可以這樣進(jìn)行搜索:
【C++】無(wú)重復(fù)數(shù)字全排列(三種方法)和有重復(fù)數(shù)字全排列,計(jì)算機(jī)算法分析與設(shè)計(jì)第五版(王曉東),c++,深度優(yōu)先,回溯法
?假設(shè)有 3 個(gè)空位,從前往后填數(shù)字,每次填一個(gè)位置,填的數(shù)字不能和前面一樣。

?最開(kāi)始的時(shí)候,三個(gè)空位都是空的:__ __ __

?首先填寫(xiě)第一個(gè)空位,第一個(gè)空位可以填 1,填寫(xiě)后為:1 __ __

?填好第一個(gè)空位,填第二個(gè)空位,第二個(gè)空位可以填 2,填寫(xiě)后為:1 2 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 3,填寫(xiě)后為: 1 2 3

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):1 2 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 3 ,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):1 __ __。第二個(gè)空位上除了填過(guò)的 2,還可以填 3。第二個(gè)空位上填寫(xiě) 3,填寫(xiě)后為:1 3 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 2,填寫(xiě)后為: 1 3 2

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):1 3 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 2,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):1 __ __。第二個(gè)空位上除了填過(guò)的 2,3,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):__ __ __。第一個(gè)空位上除了填過(guò)的 1,還可以填 2。第一個(gè)空位上填寫(xiě) 2,填寫(xiě)后為:2 __ __

?填好第一個(gè)空位,填第二個(gè)空位,第二個(gè)空位可以填 1,填寫(xiě)后為:2 1 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 3,填寫(xiě)后為:2 1 3

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):2 1 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 3,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):2 __ __。第二個(gè)空位上除了填過(guò)的 1,還可以填 3。第二個(gè)空位上填寫(xiě) 3,填寫(xiě)后為:2 3 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 1,填寫(xiě)后為:2 3 1

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):2 3 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 1,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):2 __ __。第二個(gè)空位上除了填過(guò)的 1,3,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):__ __ __。第一個(gè)空位上除了填過(guò)的 1,2,還可以填 3。第一個(gè)空位上填寫(xiě) 3,填寫(xiě)后為:3 __ __

?填好第一個(gè)空位,填第二個(gè)空位,第二個(gè)空位可以填 1,填寫(xiě)后為:3 1 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 2,填寫(xiě)后為:3 1 2

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):3 1 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 2,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):3 __ __。第二個(gè)空位上除了填過(guò)的 1,還可以填 2。第二個(gè)空位上填寫(xiě) 2,填寫(xiě)后為:3 2 __

?填好第二個(gè)空位,填第三個(gè)空位,第三個(gè)空位可以填 1,填寫(xiě)后為:3 2 1

?這時(shí)候,空位填完,無(wú)法繼續(xù)填數(shù),所以這是一種方案,輸出。

?然后往后退一步,退到了狀態(tài):3 2 __ 。剩余第三個(gè)空位沒(méi)有填數(shù)。第三個(gè)空位上除了填過(guò)的 1,2,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):3 __ __。第二個(gè)空位上除了填過(guò)的 1,2,沒(méi)有其他數(shù)字可以填。

?因此再往后退一步,退到了狀態(tài):__ __ __。第一個(gè)空位上除了填過(guò)的 1,2,3,沒(méi)有其他數(shù)字可以填。

?此時(shí)深度優(yōu)先搜索結(jié)束,輸出了所有的方案。

輸入樣例:
3
輸出樣例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

時(shí)間復(fù)雜度為 O ( n ? n ! ) O(n*n!) O(n?n!)。

1.2.2 代碼編寫(xiě)

?用 p a t h path path 數(shù)組保存排列,當(dāng)排列的長(zhǎng)度為 n n n 時(shí),是一種方案,輸出。
?用 s t a t e state state 數(shù)組表示數(shù)字是否用過(guò)。當(dāng) s t a t e [ i ] state[i] state[i] 1 1 1 時(shí): i i i 已經(jīng)被用過(guò), s t a t e [ i ] state[i] state[i] 0 0 0 時(shí), i i i 沒(méi)有被用過(guò)。
? d f s ( i ) dfs(i) dfs(i) 表示的含義是:在 p a t h [ i ] path[i] path[i] 處填寫(xiě)數(shù)字,然后遞歸的在下一個(gè)位置填寫(xiě)數(shù)字。
?回溯:第 i i i 個(gè)位置填寫(xiě)某個(gè)數(shù)字的所有情況都遍歷后, 第 i i i 個(gè)位置填寫(xiě)下一個(gè)數(shù)字。

#include<iostream>
using namespace std;
const int N = 10;
int path[N];  //保存序列
int state[N]; //數(shù)字是否被用過(guò)
int n;
void dfs(int u)
{
    if(u > n)//數(shù)字填完了,輸出
    {
        for(int i = 1; i <= n; i++) //輸出方案
            cout << path[i] << " ";
        cout << endl;
    }

    for(int i = 1; i <= n; i++) //空位上可以選擇的數(shù)字為:1 ~ n
    {
        if(!state[i])    //如果數(shù)字 i 沒(méi)有被用過(guò)
        {
            path[u] = i; //放入空位
            state[i] = 1;//數(shù)字被用,修改狀態(tài)
            dfs(u + 1);  //填下一個(gè)位
            state[i] = 0;//回溯,取出 i
        }
    }
}

int main()
{

    cin >> n;
    dfs(1);
    return 0;
}

1.3 用交換法

?交換法思想就是定下一個(gè)前綴,然后將后面的數(shù)全排列。

#include<iostream>
using namespace std;
int n;
//int cnt = 0; cnt用來(lái)計(jì)數(shù)的 
void Permutation(int *s,int p) //從數(shù)組s的第p個(gè)位置開(kāi)始全排列
{
    if(p==n)
    {
        for(int i=0;i<n;i++) 
        {
        	cout<<s[i];
	    }
	    cout<<endl;
        //可計(jì)數(shù)有多少種排序cnt++;
    }
    for(int i=p;i<n;i++)
    {
        swap(s[i],s[p]);  //每個(gè)字符都有成為當(dāng)前起始字符的機(jī)會(huì)
        Permutation(s,p+1);
        swap(s[i],s[p]);  //返回初始狀態(tài),才能保證后面的交換是正確的,回溯
    }
}
int main()
{
	cin>>n;
    int s[n];
    for(int i=0;i<n;i++) 
    {
    	s[i]=i+1;
	}
    Permutation(s,0);
    //cout <<cnt << endl; 可輸出有多少中排序 
    return 0;
}

1.4 STL秒解

1.4.1 所用函數(shù)

?1. next_permutation的功能是生成給定序列的下一個(gè)字典序排列。這個(gè)函數(shù)在C++ STL中,對(duì)于解決排列組合問(wèn)題和迭代遍歷所有可能排列時(shí)非常有用。
?2. prev_permutation的功能是生成給定序列的前一個(gè)字典序排列。這個(gè)函數(shù)在C++ STL中,可以用于迭代遍歷所有可能的排列,與next_permutation相反,它是從大到小的順序生成排列。

1.4.2 代碼編寫(xiě)

#include <iostream>
#include<algorithm> //頭文件
using namespace std;
int main()
{
	int n;
	cin>>n;
    int s[n];
    for(int i=0;i<n;i++) 
    {
    	s[i]=i+1;
	}
    //int cnt = 0;
    do
    {
        for(int i=0;i<n;i++) 
        {
        	cout<<s[i];
	    }
	    cout<<endl;
    }while(next_permutation(s,s+n));//起始位置,左閉右開(kāi)
    
    //cout<<"總共有:"<<cnt<<" 種排列"<<endl;
    return 0;
}

二、有重復(fù)數(shù)字排列

2.1 思路分析

?1. 看到這個(gè)題目首先能想到的一點(diǎn)就是:(1) 我們要求元素的所有全排列。(2) 我們要對(duì)求出的全排列去重。

?2. 求全排列用交換遞歸;去重我們可以設(shè)計(jì)一個(gè)函數(shù)來(lái)判斷這個(gè)元素是否前面已經(jīng)用到過(guò)了。

2.2 代碼編寫(xiě)

#include <iostream>
using namespace std;
int count=0;
void swap(char &a,char &b)
{
	char temp;
	temp=a;
	a=b;
	b=temp;
}
int finish(char list[],int k,int i)
{   //第i個(gè)元素是否在前面元素[k...i-1]中出現(xiàn)過(guò)
	if(i>k)
	{
		for(int j=k;j<i;j++)
			if(list[j]==list[i])
				return 0;
	}
	return 1;
}
void perm(char list[],int k,int m)
{
	if(k==m)    //當(dāng)只剩下一個(gè)元素時(shí)則輸出
	{
		count++;
		for(int i=0;i<=m;i++)
			cout<<list[i];
		cout<<endl;
	}
	for(int i=k;i<=m;i++)  //還有多個(gè)元素待排列,遞歸產(chǎn)生排列
	{
		if(finish(list,k,i))
		{
			swap(list[k],list[i]);
			perm(list,k+1,m);
			swap(list[k],list[i]);
		}
	}
}
int main()
{
	int i,n;
	cout<<"請(qǐng)輸入元素個(gè)數(shù): "<<endl;
	cin>>n;
	cout<<"請(qǐng)輸入待排列的元素: "<<endl;
	//getchar();
	char *a=new char[n];
 
	for(i=0;i<n;i++)
		cin>>a[i];
	cout<<"所有不同排列為: "<<endl;
	perm(a,0,n-1);
	cout<<"排列總數(shù)為: "<<count<<endl;
	return 0;
}

【C++】無(wú)重復(fù)數(shù)字全排列(三種方法)和有重復(fù)數(shù)字全排列,計(jì)算機(jī)算法分析與設(shè)計(jì)第五版(王曉東),c++,深度優(yōu)先,回溯法文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-739909.html

到了這里,關(guān)于【C++】無(wú)重復(fù)數(shù)字全排列(三種方法)和有重復(fù)數(shù)字全排列的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【無(wú)重復(fù)字符的最長(zhǎng)子串--三種方法】

    【無(wú)重復(fù)字符的最長(zhǎng)子串--三種方法】

    大家好,今天我們來(lái)討論一下LeetCode上兩道數(shù)組方面的例題來(lái)為大家講解滑動(dòng)窗口的使用。 題目不難,方法很多。熊貓希望通過(guò)第一道簡(jiǎn)單的題目來(lái)使大家了解到不同的解題方法。 題目描述:給定一個(gè)字符串 s ,請(qǐng)你找出其中不含有重復(fù)字符的 最長(zhǎng)子串 的長(zhǎng)度。 點(diǎn)擊跳轉(zhuǎn)

    2024年01月18日
    瀏覽(13)
  • Python 判斷列表里是否有重復(fù)元素的三種方法

    一、用 set 方法去重后與原列表長(zhǎng)度比較 二、用 append 的方式把原列表中的元素添加到一個(gè)新列表,確保新列表里不存在重復(fù)的元素,然后比較兩個(gè)列表 三、用 fromkeys 的方法創(chuàng)建一個(gè)字典,因?yàn)樽值涞逆I會(huì)自動(dòng)去重,所以可以比較字典和原列表的長(zhǎng)度,跟方法一很像

    2024年02月11日
    瀏覽(24)
  • 符號(hào)三角形-計(jì)算機(jī)算法設(shè)計(jì)與分析【1600+字解析 dfs全排列 列舉情況】【題意分析】【算法分析】【思路是怎么來(lái)的】【過(guò)程是什么】

    符號(hào)三角形-計(jì)算機(jī)算法設(shè)計(jì)與分析【1600+字解析 dfs全排列 列舉情況】【題意分析】【算法分析】【思路是怎么來(lái)的】【過(guò)程是什么】

    下圖是由14個(gè)“+”和14個(gè)“-”組成的符號(hào)三角形。2個(gè)同號(hào)下面都是“+”,2個(gè)異號(hào)下面都是“-”。 在一般情況下,符號(hào)三角形的第一行有n個(gè)符號(hào)。符號(hào)三角形問(wèn)題要求對(duì)于給定的n,計(jì)算有多少個(gè)不同的符號(hào)三角形,使其所含的“+”和“-”的個(gè)數(shù)相同。 題意分析 也就是 給

    2024年02月03日
    瀏覽(23)
  • 安卓開(kāi)發(fā)學(xué)習(xí)之設(shè)計(jì)三種計(jì)算機(jī)界面

    安卓開(kāi)發(fā)學(xué)習(xí)之設(shè)計(jì)三種計(jì)算機(jī)界面

    1.簡(jiǎn)單的計(jì)算器 2.科學(xué)計(jì)算器 3.程序計(jì)算器 不用實(shí)現(xiàn)具體功能,只需設(shè)計(jì)界面即可! 為了更好的在三個(gè)界面之間跳轉(zhuǎn),添加一個(gè)主界面。 activity_main.xml 線性布局中添加4個(gè)按鈕 界面效果: 簡(jiǎn)單計(jì)算器: chengxujishuanqi.xml 界面效果: 科學(xué)計(jì)算器: kexuejishuanqi.xml 界面效果: 程序

    2023年04月08日
    瀏覽(21)
  • 為什么計(jì)算機(jī)對(duì)浮點(diǎn)型數(shù)字計(jì)算存在誤差

    為什么計(jì)算機(jī)對(duì)浮點(diǎn)型數(shù)字計(jì)算存在誤差

    我們輸入的十進(jìn)制小數(shù)在計(jì)算機(jī)中都是以二進(jìn)制進(jìn)行存儲(chǔ)。比如: 由此可見(jiàn)0.3在計(jì)算機(jī)中存儲(chǔ)的值永遠(yuǎn)小于0.3,所以當(dāng)使用0.3計(jì)算時(shí),就會(huì)產(chǎn)生誤差。 在計(jì)算機(jī)中浮點(diǎn)型不能直接使用等號(hào)比較也是同一個(gè)道理。舉個(gè)李子: 執(zhí)行結(jié)果: 可以看出當(dāng)涉及到0.3的運(yùn)算超出一定的精

    2023年04月11日
    瀏覽(30)
  • C++ STL第三篇(搞清楚deque原理和有多少用法)

    C++ STL第三篇(搞清楚deque原理和有多少用法)

    Vector容器是單向開(kāi)口的連續(xù)內(nèi)存空間,deque則是一種雙向開(kāi)口的連續(xù)線性空間。所謂的雙向開(kāi)口,意思是可以在頭尾兩端分別做元素的插入和刪除操作,當(dāng)然,vector容器也可以在頭尾兩端插入元素,但是在其頭部操作效率奇差,無(wú)法被接受。 Deque容器和vector容器最大的差異,

    2024年03月17日
    瀏覽(23)
  • 計(jì)算機(jī)數(shù)字編碼入門(mén)篇(下)

    本文旨在為初學(xué)者提供有關(guān)計(jì)算機(jī)數(shù)字編碼的基礎(chǔ)知識(shí),以幫助他們初步理解計(jì)算機(jī)中數(shù)字編碼的概念。鑒于我個(gè)人知識(shí)的限制,如有不準(zhǔn)確之處,歡迎指正并提供建議。 文中部分內(nèi)容參考ChatGPT,在此感謝ppword的大力支持。 定點(diǎn)數(shù),其關(guān)鍵地方就在“定”和“點(diǎn)”這兩個(gè)字

    2024年02月08日
    瀏覽(19)
  • 【計(jì)算機(jī)組成原理】高速緩沖存儲(chǔ)器 Cache 的三種映射方式(Cache Mapping)

    【計(jì)算機(jī)組成原理】高速緩沖存儲(chǔ)器 Cache 的三種映射方式(Cache Mapping)

    緩存是計(jì)算機(jī)系統(tǒng)中常見(jiàn)的一種高速存儲(chǔ)器,用于臨時(shí)存儲(chǔ)常用數(shù)據(jù),以便快速訪問(wèn)。在緩存中,有三種常見(jiàn)的映射方式,分別是直接映射、全相聯(lián)映射和組相聯(lián)映射。 在直接映射中,每個(gè)主存塊只能映射到緩存中的一個(gè)特定位置。該位置是通過(guò)對(duì)主存塊的某個(gè)地址的一部分

    2024年01月19日
    瀏覽(28)
  • 計(jì)算機(jī)視覺(jué):窺探數(shù)字世界的眼睛

    計(jì)算機(jī)視覺(jué):窺探數(shù)字世界的眼睛

    目錄 簡(jiǎn)介: 一. 計(jì)算機(jī)視覺(jué)的起源與發(fā)展 二. 計(jì)算機(jī)視覺(jué)的應(yīng)用領(lǐng)域 三. 計(jì)算機(jī)視覺(jué)的挑戰(zhàn)與未來(lái)發(fā)展 結(jié)論: 計(jì)算機(jī)視覺(jué)(Computer Vision)是人工智能(AI)領(lǐng)域中的一個(gè)重要分支,專(zhuān)注于研究如何使計(jì)算機(jī)系統(tǒng)能夠“看見(jiàn)”、理解和解釋圖像和視頻的技術(shù)。它旨在模擬人類(lèi)

    2024年02月12日
    瀏覽(16)
  • 【計(jì)算機(jī)視覺(jué)】數(shù)字圖像處理(六)—— 圖像壓縮

    【計(jì)算機(jī)視覺(jué)】數(shù)字圖像處理(六)—— 圖像壓縮

    (一)、圖像編碼技術(shù)的研究背景 1. 信息信息傳輸方式發(fā)生了很大的改變 通信方式的改變 文字+語(yǔ)音 圖像+文字+語(yǔ)音 通信對(duì)象的改變 人與人 人與機(jī)器,機(jī)器與機(jī)器 2. 圖像傳輸與存儲(chǔ)需要的信息量空間 (1)彩色視頻信息 對(duì)于電視畫(huà)面的分辨率640 480的彩色圖像,每秒30幀,

    2024年02月05日
    瀏覽(96)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包