字符串的全排列问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
有限个字符排列,相邻字符有限制,求排列方式。
2009-10-27 8:40
递推:
现须求排列方式数f[n],则列出所有前n-1个字符与最后一个字符的组合。
XXXXXXO E,F
XXXXXXE E,F,O
XXXXXXF E,F,O
可知无论前n-1个字符是什么,第n个字符取E或F都不符合要求,这种情况下,有2*f[n-1]中排列方式。如果第n-1个字符是E 情况下,有2*f[n-2]种排列方式。
递推公式:f[n] = 2*f[n-1] + 2*f[n-2];
递推(剪去不符合要求的情况):
不符合要求的情况:
XXXXXEOO
F
即第n,n-1个字符由OO组成,第n-2个字符可以是E或F,第0...n-3个字符任取,有2*f[n-3]种排列方式。
递推公式:f[n] = 3*f[n-1] - 2*f[n-3]。
动态规划:
定义长度为n,第n个字符为i的排列方式数为f[n][i]。其中i取0代表最后一个字符为O,i=1为E,i=2为F。
f[n][0] = f[n-1][1] + f[n-1][2]
f[n][1] = f[n-1][0] + f[n-1][1] + f[n-1][2]
f[n][2] = f[n-1][0] + f[n-1][1] + f[n-1][2]
可知f[n][1]==f[n][2],则式子可变换为:
f[n][0] = 2*f[n-1][1];
f[n][1] = f[n-1][0] + f[n][0];
初始化f[1][0]=1,f[1][1]=1;
长度为n的字符串排列方式数= f[n][0] + 2*f[n][1]
#include "iostream"
//__int64 f[40] = {1,3};
__int64 f[40][2] = {0,0,1,1};
//void init()
//{
// for(int i=2;i<40;i++)
// f[i] = 2*(f[i-1]+f[i-2]);
//}
void init2()
{
for(int i=2;i<40;i++)
{
f[i][0] = 2*f[i-1][1];
f[i][1] = f[i-1][0] + f[i][0];
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int k;
init2();
while(scanf("%d",&k)!=EOF)
printf("%I64d\n",f[k][0] + 2*f[k][1]);
return 0;
}
分类: 2011-09-10 15:12 72人阅读 (0) 去参加一个笔试,遇到一个问题就是给定字符串"123456"要我写程序输出所有的排列组合方式,当时头很大,一直想不出来,于是很磋的写了循环。回来了好好想了想,参考网上的资料,今天真正理解并且自己写了出来。是用递归,理解为每次都是求已知的字符串与未排列的字符串的组合!
1./*
2.2011-9-9
3.author:BearFly1990
4.*/
5.package temp;
6.public class RecursionString {
7.public static void main(String[] args) {
8. String b = "123456";
9. doit("",b);
10. }
11.public static void doit(String a,String b){
12.if(a.length()== 6){
13. ;
14. }else{
15.for(int i = 0; i< b.length(); i++){
16. String tempa = new String(a);
17. String tempb = new String(b);
18. doit(tempa+tempb.charAt(i),new String
Builder(tempb)
19. .deleteCharAt(i).toString());
20. }
21. }
22. }
23.}
一个双重循环的算法:
public static void main(String[] args){
char a[]={'1','2','2','3','4','5'};
int i , j;
//双重循环,交换数据
for(i = 0 ; i < a.length; i ++){//第一个数下标
for(j = 0 ; j < a.length; j ++){//第二个数下标
//交换
char temp = a[i];
a[i]= a[j];
a[j]= temp;
String s =String.valueOf(a);
//判断输出
if( s.charAt(2)!='4'//4不出现在第三位
&& s.indexOf("53")==-1 //不存在53
&& s.indexOf("35")==-1){//不存在35
//输出
;
}