當前位置:首頁 » 編程語言 » c語言全排列遞歸

c語言全排列遞歸

發布時間: 2022-09-03 12:44:46

1. c語言的全排列問題!急!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int hash[27];
char word[201];
int n;
void dfs(int cur)
{
if(cur>=n)
{
printf("%s\n",word);
return ;
}
int i;
for(i=0;i<26;i++)
if(hash[i])
{
hash[i]--;
word[cur]=i+'a';
dfs(cur+1);
hash[i]++;
}
return ;
}
int main()
{
int i;
scanf("%s",word);
n=strlen(word);
memset(hash,0,sizeof(hash));
for(i=0;i<n;i++)
hash[word[i]-'a']++;
dfs(0);
return 0;
}

樓主看一下,輸入一行字元,輸出全排列,多個案例的話最外面加個while循環就是了

2. 求解C/C++一個字元串的遞歸全排列的問題

Swap(list[k],list[i]);//從第一個元素起,後面的元素依次與第一個元素交換.
Perm(list,k+1,m);//遞歸調用,直至一個全排列完成,即k等於m.
Swap(list[k],list[i]);//將第一個Swap所換過的元素進行還原,防止遺漏和重復.

// 如果你懂得河內塔(漢諾塔)遞歸的整個內部執行過程,那麼這個全排列的遞歸(包括組合數的遞歸)就很簡單了。

3. C語言如何實現有重復元素的全排列

在遞歸裡面用交換的方式獲取全排列,從第一個開始,不斷與後面數交換,當然遞歸時不要忘記在後面寫個換回來的語句。只要加個交換條件就可以了,在不相等時交換,相等時不交換。

當前階段,在編程領域中,C語言的運用非常之多,它兼顧了高級語言和匯編語言的優點,相較於其它編程語言具有較大優勢。計算機系統設計以及應用程序編寫是C語言應用的兩大領域。同時,C語言的普適較強,在許多計算機操作系統中都能夠得到適用,且效率顯著。

C語言擁有經過了漫長發展歷史的完整的理論體系,在編程語言中具有舉足輕重的地位。



特有特點

C語言是普適性最強的一種計算機程序編輯語言,它不僅可以發揮出高級編程語言的功用,還具有匯編語言的優點,因此相對於其它編程語言,它具有自己獨特的特點。具體體現為以下三個方面:

其一,廣泛性。C語言的運算范圍的大小直接決定了其優劣性。C語言中包含了34種運算符,因此運算范圍要超出許多其它語言,此外其運算結果的表達形式也十分豐富。此外,C語言包含了字元型、指針型等多種數據結構形式,因此,更為龐大的數據結構運算它也可以應付。

其二,簡潔性。9類控制語句和32個關鍵字是C語言所具有的基礎特性,使得其在計算機應用程序編寫中具有廣泛的適用性,不僅可以適用廣大編程人員的操作,提高其工作效率,同時還能夠支持高級編程,避免了語言切換的繁瑣。

其三,結構完善。C語言是一種結構化語言,它可以通過組建模塊單位的形式實現模塊化的應用程序,在系統描述方面具有顯著優勢,同時這一特性也使得它能夠適應多種不同的編程要求,且執行效率高。

4. C語言中全排列問題思路

方法1:如果位數不多窮舉
方法2:位數多建議遞歸。

5. c語言,遞歸1~n按字典順序全排列

#includevoidswap(char&a,char&b,charc){c=a;a=b;b=c;}voidperm(char*list,inti,intn){intj,temp;if(i==n){for(j=0;j<=n;j++)printf("%c",list[j]);printf("");}else{for(j=i;j<=n;j++){swap(list[i],list[j],temp);perm(list,i+1,n);swap(list[i],list[j],temp);}}}voidmain(){charlist[3]={'A','B','C'};perm(list,0,2);}

6. C的遞歸的全排列問題(不知道的哪涼快上哪去,別在這嗶嗶亂吠!不懂裝懂,讓人惡心)。

簡單的說遞歸就是一個入棧和出棧的過程,但這個裡面有循環,所以有點復雜

#include <stdio.h>

void Perm(char *list, int k, int m)
{
int i;
char t;

if (k == m)
{
puts(list);
}
else
{
for (i=k; i<m; i++)
{
t = list[i];
list[i] = list[k];
list[k] = t;

Perm(list, k+1, m);

t = list[i];
list[i] = list[k];
list[k] = t;
}
}
}

void main(void)
{
Perm("123", 0, 3);
}

為了簡便,我只對123進行全排列

這個裡面有兩次交換,第一個交換函數是發生在入棧過程,第二個交換函數是發生在出棧過程
--(A)-->表示調用第一個交換函數後,--(B)-->表示調用第二個交換函數後

第一次調用Prem函數一共有三次循環,分別是(1)k =0, i = 0; (2)k = 0, i = 1; (3)k = 0, i = 2
我只給你講第一次循環過程,後兩次自己分析

入棧過程:
Prem --> (k=0,i=k) --(A)--> 內容"123" --> Prem --> (k=1,i=k) --(A)-->內容"123" --> Prem --> (k=2,i=k) --(A)--> 內容"123" --> Prem -->k=3輸出
開始退棧:
--> (k=2,i=k) --(B)--> 內容"123"(注意:這里此後還要執行一次i++,但i=3不滿足i<3,退出循環,後面我都會省略掉) --> (k=1,i=k) --(B)--> 內容"123" --> i++(此時i=2,而k=1)
又一次入棧(這是中間時候的入棧,排列數越多,中間入棧的次數越多,三個數排列只有一次中間入棧過程)
--> (k=1,i=2) --(A)--> 內容"132" --> Perm --> (k=2,i=k) --(A)--> 內容"132" --> Prem --> k=3輸出
又開始退棧
--> (k=2,i=k) --(B)--> 內容"132" --> (k=1, i=2) --(B)-->內容"123" -->最後到達第一次循環的起始點,在執行i++進行第二次循環

樓主因該發現第一次交換是對裡面數據的交換,產生排列組合
第二個交換是還原最初的輸入數據

第一次循環123首先把1單獨放出來,對2和3交換(也就是中間入棧過程)
第二次循環123首先把2單獨放出來,對1和3交換
第三次循環123首先把3單獨放出來,對1和2交換

7. C語言 求此全排列遞歸演算法解析

used數組是全局變數有隱含初值0;
關於全排列的演算法你可以理解為深搜加回溯。
#include<stdio.h>
#define
MAX
10
int
used[MAX];
//用來標記數字是否已經在前面使用過
int
result[MAX];
//存放結果
int
N;
void
print()
//輸出結果
{
int
i;
for(i=0;i<N;i++)
printf("%d
",result[i]);
printf("\n");
}
void
proc(int
step)
//step用來記錄已經擺好了幾個數
{
int
i;
if(step==N)
//如果已經擺好了N個數,那麼結果就產生了,就輸出結果
print();
else
{
for(i=0;i<N;i++)
//枚舉1-N,找到沒有使用過的最小的數
{
if(!used[i])
//沒有使用過
{
used[i]=1;
//標記i已經使用
result[step]=i+1;
//記錄結果
proc(step+1);
//遞歸求解
used[i]=0;
//這里就是所謂的回溯,也許比較難理解,你可以人工走一遍加深理解。其實回溯的主要想法是"還原現場".當執行到這一步時,i+1
這個數放在第step個位置的情況已經解決了,我們就要拿出i+1這個數,把它標記為未使用。
}
}
}
}
int
main()
{
scanf("%d",&N);
proc(0);
return
0;
}

8. 全排列遞歸演算法

希望我的答復可以幫助你加深理解:

第一,perm函數中的條件for(int i=k;i<=m;i++)應更正為 for(int i=k;i<m;i++)

第二,你可以在核心步驟的前後列印有關變數的值,分析查看每一步的具體執行情況,這是編程調試的重要能力,要加強。
第三,以下是我提供的附件程序及運行結果(以1,2,3這個數組的全排列),可輔助分析:

1. 程序源碼=================================================
#include <stdio.h>
#include <stdlib.h>
int N,P=0;

void swap(int a[],int i,int j)
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}

void perm(int a[],int k,int m,int pk,int pm)
{
int i;
/*k為中間變數,m初始化為參與排列元素的起始坐標和終止坐標
pk,pm分別表示參與排列元素的起始坐標和終止坐標,整個遞歸過程保持不變*/
if(k==m)
{
printf("----->perm %d :\n",P/N+1);/*列印提示*/
for(i=pk;i<pm;i++)
{
printf("%d ",a[i]);
P=P+1;
}
printf("\n\n");
}
else
{
for(i=k;i<m;i++)
{
printf("a %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
swap(a,k,i);
printf("b %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
perm(a,k+1,m,pk,pm);
printf("c %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
swap(a,k,i);
printf("d %d,%d,%d,%d,%d\n",i,k,a[0],a[1],a[2]);
}
}
}

int main()
{
/*調節以下N值及對應數組內容,可列印對應數組對應的全排列*/
N=3;
int t[]={1,2,3};
/*調節以上N值及對應數組內容,可列印對應數組對應的全排列*/

perm(t,0,N,0,N);
printf("----->Over!\n");/*列印提示*/
system("pause");
return 0;
}

2.列印結果 ============================================================

a 0,0,1,2,3
b 0,0,1,2,3
a 1,1,1,2,3
b 1,1,1,2,3
a 2,2,1,2,3
b 2,2,1,2,3
----->perm 1 :
1 2 3

c 2,2,1,2,3
d 2,2,1,2,3
c 1,1,1,2,3
d 1,1,1,2,3
a 2,1,1,2,3
b 2,1,1,3,2
a 2,2,1,3,2
b 2,2,1,3,2
----->perm 2 :
1 3 2

c 2,2,1,3,2
d 2,2,1,3,2
c 2,1,1,3,2
d 2,1,1,2,3
c 0,0,1,2,3
d 0,0,1,2,3
a 1,0,1,2,3
b 1,0,2,1,3
a 1,1,2,1,3
b 1,1,2,1,3
a 2,2,2,1,3
b 2,2,2,1,3
----->perm 3 :
2 1 3

c 2,2,2,1,3
d 2,2,2,1,3
c 1,1,2,1,3
d 1,1,2,1,3
a 2,1,2,1,3
b 2,1,2,3,1
a 2,2,2,3,1
b 2,2,2,3,1
----->perm 4 :
2 3 1

c 2,2,2,3,1
d 2,2,2,3,1
c 2,1,2,3,1
d 2,1,2,1,3
c 1,0,2,1,3
d 1,0,1,2,3
a 2,0,1,2,3
b 2,0,3,2,1
a 1,1,3,2,1
b 1,1,3,2,1
a 2,2,3,2,1
b 2,2,3,2,1
----->perm 5 :
3 2 1

c 2,2,3,2,1
d 2,2,3,2,1
c 1,1,3,2,1
d 1,1,3,2,1
a 2,1,3,2,1
b 2,1,3,1,2
a 2,2,3,1,2
b 2,2,3,1,2
----->perm 6 :
3 1 2

c 2,2,3,1,2
d 2,2,3,1,2
c 2,1,3,1,2
d 2,1,3,2,1
c 2,0,3,2,1
d 2,0,1,2,3
----->Over!
請按任意鍵繼續. . .

9. 遞歸全排列 c語言 看不懂

perm(list,i,j)是一個全排列函數,拿你上面的列子來說:
perm(list,0,5)意思是數組list的前6個數(第0個數到第5個數)的所有排列,它細分的話就等於:第0個數和第1個數互換以後的perm(list,1,5) 第0數和第2數互換perm(list,1,5) ....第0數和第5數互換的perm(list,1,5) 和它本身的所在0位置的perm(list, 1, 5)
如假如6個數是1 2 3 4 5 6
他們的排列就 * * * * * * perm(list,0,5)
1 * * * * * perm(list,1,5)
2 * * * * * perm(list,1,5)
3 * * * * * perm(list,1,5)
4 * * * * * perm(list,1,5)
5 * * * * * perm(list,1,5)
6 * * * * * perm(list,1,5) 就是每一個數都在第0個位置上面都出現一次以後的排列總和。 也就是它的for循環的意思
這只是形象的比喻一下

10. C語言遞歸問題(全排列)

#include <stdio.h>

void swap(char &a,char &b,char c)
{
c=a; a=b; b=c;
}

void perm (char*list,int i,int n)
{
int j,temp;
if(i==n)
{
for(j=0;j<=n;j++)
printf("%c",list[j]);
printf(" ");
}
else
{
for(j=i;j<=n;j++)
{
swap(list[i],list[j],temp);
perm(list,i+1,n);
swap(list[i],list[j],temp);
}
}
}

void main()
{
char list[3]={'A','B','C'};
perm(list,0,2);
}

熱點內容
android文件圖片 發布:2025-01-15 17:39:44 瀏覽:205
linux的路徑怎麼寫 發布:2025-01-15 17:18:49 瀏覽:185
php解壓程序 發布:2025-01-15 17:06:22 瀏覽:142
刷助力腳本 發布:2025-01-15 17:02:31 瀏覽:520
c盤里的用戶文件夾可以刪除 發布:2025-01-15 16:56:45 瀏覽:951
虛幻4編譯到哪裡 發布:2025-01-15 16:50:19 瀏覽:756
透明度漸變android 發布:2025-01-15 16:45:08 瀏覽:835
dos連接oracle資料庫 發布:2025-01-15 16:41:39 瀏覽:906
網路配置比較低怎麼做 發布:2025-01-15 16:35:38 瀏覽:362
android彈出鍵盤監聽 發布:2025-01-15 16:35:11 瀏覽:208