打印出已知字符串的所有排列组合,比如给出"abc",打印abc,acb,bac,bca,cab,cba.
所有可能个数是n!,n为字符串长度。
数学表达:
E={e1,e2,e3,...en}.表示字符串的集合,令Ei为移去ei后的集合,perm(X)表示集合X的所有元素排列。ei.perm(X)表示在perm(X)的基础上加前缀ei.
例如:E={a,b,c}, E1={b,c},perm(E1)={bc,cb}, e1.perm(E1)={abc,acb}
当n=1时,perm{E}={e},只有一种组合
当n>1时,perm{E}=e1.perm{e1}+e2.perm{e2}+...en.perm{en}
递归定义结束。
例子:
当n=3, E={a,b,c}
perm{E}=a.perm({b,c})+b.perm({a,c})+c.perm({a,b})
perm({b,c})=b.perm({c})+c.perm({b})=bc+cb
perm({a,c})=a.perm({c})+c.perm({a})=ac+ca
perm({a,b})=ab+ba
当n=4,E={a,b,c,d}
perm{E}=a.perm{b,c,d}+b.perm({a,c,d})+c.perm({a,b,d})+d.perm({a,b,c})
所有可能个数是n!,n为字符串长度。
数学表达:
E={e1,e2,e3,...en}.表示字符串的集合,令Ei为移去ei后的集合,perm(X)表示集合X的所有元素排列。ei.perm(X)表示在perm(X)的基础上加前缀ei.
例如:E={a,b,c}, E1={b,c},perm(E1)={bc,cb}, e1.perm(E1)={abc,acb}
当n=1时,perm{E}={e},只有一种组合
当n>1时,perm{E}=e1.perm{e1}+e2.perm{e2}+...en.perm{en}
递归定义结束。
例子:
当n=3, E={a,b,c}
perm{E}=a.perm({b,c})+b.perm({a,c})+c.perm({a,b})
perm({b,c})=b.perm({c})+c.perm({b})=bc+cb
perm({a,c})=a.perm({c})+c.perm({a})=ac+ca
perm({a,b})=ab+ba
当n=4,E={a,b,c,d}
perm{E}=a.perm{b,c,d}+b.perm({a,c,d})+c.perm({a,b,d})+d.perm({a,b,c})
- template<class T>
- inline void Swap(T &a, T &b)
- {
- T temp = a;
- a = b;
- b = temp;
- }
- template<class T>
- void Perm(T list[], int k, int m)
- {//生成list[k:m]的所有排列方式
- int i;
- if (k == m)
- { //输出一种
- for (i=0; i<=m; i++)
- {
- cout << list[i];
- }
- cout << endl;
- }
- else
- {// 找出list[k:m]的所有排列方式
- for (i=k; i<=m; i++)
- {
- //循环次数为m-k+1次
- //只变k~m范围的元素,0~k-1作为前缀不变
- Swap(list[k], list[i]);
- Perm(list, k+1, m);
- Swap(list[k], list[i]);
- }
- }
- }
本文详细介绍了如何通过递归算法生成给定字符串的所有可能排列组合,并提供了具体的C++实现代码。通过对递归过程的逐步分解,读者可以清晰地理解算法背后的逻辑及其实现细节。
8531

被折叠的 条评论
为什么被折叠?



