您的位置:首页 > 其它

字符串排列递归和非递归实现

2013-04-06 15:54 316 查看
求一个全排列函数:p([1,2,3])输出:[123]、[132]、[213]、[231]、[321]、[323]

1、递归的方法:

依次把每个字符交换到第一个位置,后面的字符做同样的递归过程。

void Permutation(char *str)
{
void PSolution(char *str, int begin, int end);
int Length;
if(str == NULL || (Length = strlen(str)) == 0)
return;
PSolution(str, 0, Length);
}

void PSolution(char *str, int begin, int end)
{
void swap(char *, char *);
if(begin == end-1)
{
cout<<str<<endl;
return;
}
for(int i = begin; i < end; ++i)
{
swap(str+i, str + begin);
PSolution(str, begin+1, end);
swap(str+i, str+ begin);
}

}

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


2、字典序的方法:

1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
3)对换pj,pk
4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
void Reverse(char *p, char *q)
{
char temp;
while(p < q)
{
temp = *p;
*p = *q;
*q = temp;
p++;
q--;
}
}
void swap(char *p, char *q)
{
char temp;
temp = *p;
*p = *q;
*q = temp;
}
int Mult(int i)
{
int sum = 1;
while(i)
{
sum *= i;
i--;
}
return sum;
}
void permutation2(char *p)
{
int i = strlen(p);
int cout = Mult(i);
int j = 0;
int pLeft, pRight;
int RMin;
printf("%s\n", p);
while(--cout)
{
for(j = i-2; j >= 0 && p[j] > p[j+1]; j--)
;
pLeft = j;
RMin = *(p+pLeft+1);
for(j = pLeft+1; j <= i-1; j++)
{
if((*(p+j) > *(p+pLeft)) && (*(p+j) <= RMin))
{
RMin = *(p+j);
pRight = j;
}
}
swap(p+pLeft, p + pRight);
Reverse(p+pLeft+1, p+i-1);
printf("%s\n", p);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐