字符串的全排列问题

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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

//输出

;

}

相关文档
最新文档