c語言全排列
㈠ c語言中全排列問題
//輸入一個數輸出這個數所有的排列,遞歸做法
#include<stdio.h>
int a[100];
int n;
void output()
{
int i;
for(i=1;i<=n;i++)
printf("%3d",a[i]);
printf("\n");
}
void Swap(int &a,int &b) //注意取地址
{
int t;
t=a;
a=b;
b=t;
}
void pailie(int t)
{
int i;
if(t==n) //輸出
{
output();
return ;
}
for(i=t;i<=n;i++)
{
Swap(a[i],a[t]); //交換
pailie(t+1);
Swap(a[t],a[i]); //換回
}
}
int main()
{
int i;
while(scanf("%d",&n)!=EOF&&n!=0)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
pailie(1);
}
return 0;
}
㈡ 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循環就是了
㈢ C語言 全排列······暈
首先,我下面的敘述是建立在樓主明白什麼是遞歸調用的基礎上的。對遞歸毫無了解的話,請先看看網路。
然後,進入正題。
第一個return:就是返回這個函數的調用者,這個函數執行完畢。這是一個if判斷,當帶排列的數列長度為1時,只有一種可能,輸出,則排列結束,返回。長度不只1的時候,執行以下for。
未完待續
接著講這個
for(i=0;i<n;i++){----------這個循環到底怎麼個看法和順序?
anagram(d,n-1); 怎麼輸出的??(這塊都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
先講這個演算法的思想,比如對abc進行全排列,那麼可以看做:ab的全排列+c和ac的全排列+b和bc的全排列+a三個的組合。然後再細化,ab的全排列可以看出a的全排列+b,和b的全排列+a兩個的組合。當只有一個時,就是調用if=1的那個情況,直接print。不是1的時候,就是遞歸調用,進行不斷地分解。
這是演算法思想,未完待續
兩個for循環,裡面的for執行一邊後就是把數組的元素挨個往前挪一位,第一位到最後位,然後對前n-1位進行全排列,遞歸進行。從上面的演算法思想中我們可以看出這樣的目的和意義,就是一個類似對上面abc的分解過程,一次a到最後排bc,一次b到最後排ac,一次c到最後排ab。
就先說這么多吧。純手打,望採納!有問題可以補充,或者網路hi我。
我幫你改了一下代碼,加了幾行printf,希望可以解決你的那幾個問題:
#include<stdio.h>
#define NUM 3
void anagram(int[],int);
void print(int[]);
void main()
{
int d[NUM];
int i;
for(i=0;i<NUM;i++)
d[i]=i + 1;
printf("初始化後的數組順序是:");
print(d);
anagram(d,NUM);
}
void anagram(int d[],int n)
{
int i,j,temp;
int p;
if(n==1){
print(d); //列印函數
return;//-------------return返回哪?
} // 和下面的for怎麼聯系起來?
for(i=0;i<n;i++){//----------這個循環到底怎麼個看法和順序?
printf("\ni = %d,n = %d, 准備調用aragram(d,%d)\n",i,n,n-1);
printf("這時候的數組順序是:");
print(d);
anagram(d,n-1); // 怎麼輸出的??(這塊都不明白)
temp=d[0];
for(j=1;j<=n-1;j++){
d[j-1]=d[j];
}
d[n-1]=temp;
}
}
void print(int d[]){
int i;
for(i=0;i<NUM;i++){
printf("%d",d[i]);
}
printf("\n");
}
PS:
改動:1、print函數原來是逆序輸出,改成正序輸出,有利於理解;2、數組原來初始化為321,改為123,有利於理解。就改了這兩個地方,加了一些printf。
你可以運行一下。
輸出結果:
初始化後的數組順序是:123
i = 0,n = 3, 准備調用aragram(d,2)
這時候的數組順序是:123
i = 0,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:123
123
i = 1,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:213
213
i = 1,n = 3, 准備調用aragram(d,2)
這時候的數組順序是:231
i = 0,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:231
231
i = 1,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:321
321
i = 2,n = 3, 准備調用aragram(d,2)
這時候的數組順序是:312
i = 0,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:312
312
i = 1,n = 2, 准備調用aragram(d,1)
這時候的數組順序是:132
132
請按任意鍵繼續. . .
㈣ 全排列用C語言實現
給,已經編譯運行確認:
#include<stdio.h>
#include<string.h>
char a[20];
int lenth;
long count=0;
void main()
{void move(int,int);
int i,j=0;
printf("input:");gets(a);
lenth=strlen(a);
for(i=0;i<lenth;i++)
move(j,i);//move a[i] to the front of a[j];
printf("\ntotal=%d\n",count);
}
void move(int here,int which)//move a[which] to the front of a[here];
{char b[20];
char temp;
int m,n;
if(here<lenth-1)
{if(here!=which)
{for(m=0;m<lenth;m++)
b[m]=a[m];
temp=a[which];
for(m=which;m>here;m--)
a[m]=a[m-1];
a[m]=temp;
}
for(n=here+1;n<lenth;n++)
move(here+1,n);
if(here!=which)
for(m=0;m<lenth;m++)
a[m]=b[m];
}
else
{printf("%-10s",a);
count++;}
}
㈤ c語言求全排列
用迭代演算法簡單些, 就是速度慢許.
演算法為:
為求1 ~ n個整數的函數 permutation,
* 如果n = 2, 只有兩種排列方式, 即 (1, 2) (2, 1)
* 迭代計算1 ~ n-1個整數的全排列
* 將n插入所得到的1 ~ n-1的全排列的任意位置得到1 ~ n的全排列.
㈥ C語言全排列問題
你的程序在swap()函數中只是將形參進行了值的對調,對實參無任何影響.
解決上述問題有兩個方法:
1.正如樓上所說的,在C++環境下,可以將swap的兩個參數改成引用類型,這樣對它們的操作將實際作用於實參,實現如下:
函數定義:swap(int &a,int &b);
函數調用示例:swap(*(p+k);*(p+i));其中p是指針,k,i是整形偏移量.
2.在純C環境下,可以將swap的兩個參數改為指針類型,而在函數內部使用對其指向的地址中數據的解引用操作,實現對原變數的對調操作,實現如下:
函數定義:
swap(int *a,int *b)
{int t;
t=*a;
*a=*b;
*b=t;
}
函數調用示例:swap(p+k,p+i);其中p是指針,k,i是整形偏移量.
你的程序中還有兩處涉及到指針使用的錯誤,我把改過的程序貼上來,錯誤已在注釋中標注.
#include "stdio.h"
swap(int *a,int *b)
{
int t;
t=*a;
*a=*b;
*b=t;
}
perm(int *p,int k,int n)
{
int i;
if(k==n-1)
{
for(i=0;i<n;i++)
printf("%d",*(p+i));
printf("\n");
}
else
{
for(i=k;i<n;i++)
{
swap((p+k),(p+i));
perm(p,k+1,n); //原為perm(*p,k+1,n).在此應傳遞的是指針p指向的地址,而不是該地址中的內容.
swap((p+k),(p+i));
}
}
}
main()
{
int i,list[3],*p;
for(i=0;i<3;i++)
list[i]=i+1;
p=list; //原為p=list[0].這里應將數組list的首地址賦值給指針p,所以就寫成p=list或p=&list[0].
perm(p,0,3);
}
㈦ 求一個c語言按字典序全排列的方法
如果是想學習一下演算法,用c語言不錯。如果是實際使用需要,就用現成的木頭超級字典生成器(MutouDic),工具集里有一個排列字典工具,可以生成任意個元素,任意長度的升序排列、降序排列和全排列。
㈧ c語言中,如何輸出一個數組的全排列!如a[3]={1,2,3} 要求輸出1 2 3,1 3 2,
#include <stdio.h>
#define N 3
int a[N];
void perm(int);
void print();
void swap(int, int);
int main()r> {
int i,n;
int offset;
for(i = 0; i<N; i++)
a[i] = i + 97;
perm(0);
}
void perm(int offset)
{
int i, temp;
if(offset == N-1)
{
print();
return;
}
for(i = offset; i < N; i++)
{
swap(i, offset);
perm(offset + 1);
swap(i, offset);
}
}
void print()
{
int i;
for(i = 0; i < N; i++)
printf(' %c ',a[i]);
printf('\n');
}
void swap(int i, int offset)
{
int temp;
temp = a[offset];
a[offset] = a[i];
a[i] = temp;
}
㈨ C語言數字全排列的問題(急!!)求C代碼和演算法
#include <stdio.h>
#include <string.h>
char string[]="123456789a";
int used[10]={0};
char output[10];
int length;
void Fun(int d)
{
int i;
for(i=0;i<=length;i++)
{
if(!used[i])
{
used[i]=1;
output[d]=string[i];
if(d==length)
{
for(d=0;d<length;d++)
{
if(output[d]=='a')
printf("10 ");
else printf("%c ",output[d]);
}
if(output[length]=='a')
printf("10\n");
else
printf("%c\n",output[length]);
}
else
Fun(d+1);
used[i]=0;
}
}
}
int main()
{
int n;
scanf("%d",&n);
string[n]=0;
length=strlen(string)-1;
Fun(0);
return 0;
}
㈩ c語言全排列
基本思想是用回溯法來搜索每一種排列
不過樓主對問題的說明不是很詳細,所以我只好寫個
普適性
比較大的了
下面這個
程序
讀取一行
字元串
,然後對該字元串中的所有
字元
進行全排列輸出
註:輸入的字元串不要太長,因為不存在能夠在短時間內輸出全排列的
演算法
#include
<stdio.h>
#include
<string.h>
#include
<memory.h>
int
m;//記錄字元串
長度
int
n;//記錄字元串中的字元
種類
數
char
map[256];//記錄是哪幾種字元
int
count[256];//記錄每種字元有多少個
void
Make_Map(char
*str)//統計字元串的相關信息
{
int
s[256];
int
i;
memset(s,0,sizeof(s));
memset(count,0,sizeof(count));
m=strlen(str);
while(*str)
{
s[*str]++;
str++;
}
n=0;
for
(i=0;i<256;i++)
if
(s[i])
{
map[n]=i;
count[n]=s[i];
n++;
}
}
int
stack[1000];//遞歸用的棧,並記錄當前生成的排列
void
Find(int
depth)//遞歸式回溯法生成全排列
{
if
(depth==m)
{
int
i;
for
(i=0;i<depth;i++)
putchar(map[stack[i]]);
putchar('\n');
}
else
{
int
i;
for
(i=0;i<n;i++)
if
(count[i])
{
stack[depth]=i;
count[i]--;
Find(depth+1);
count[i]++;
}
}
}
main()
{
char
str[1000];
gets(str);
Make_Map(str);
Find(0);
}