假设我们已有6个元素{a,b,c,d,e,f},我们要将这6个元素的一个序列改成另一个序列
比如:a b c d e f
---> c d f b e a
我们可以采用“循环记号”标记上面的改变
(acf)(bd)
表示为a-->c,c-->f,f-->a,b-->d,d-->b
在一个排列之后我们又可以应用另一个排序,我们可以将两个排列相乘
| a b c d e f | | a b c d e f | | a b c d e f |
| | * | | = | |
| c d f b e a | | b d c a f e | | c a e b f d |
显然排列乘法不满足交换率,采用循环记号,我们可以将上面的乘式写为:
(acf)(bd)(abd)(ef)=(acefb)
因此我们可以处理多项乘式相乘的结果。
循环扫描
算法流程
E1.将乘法式中的右括号替换为与之对应的左括号后一个的字符
E2.从左到右找出没有被标记过的元素(所有元素都被标记了则算法结束),将该元素赋给Start,输出左括号以及该元素,并标记该元素
E3.将当前的算式的后一个元素赋给Current
E4.向右扫描算式,如果找到Current的元素,则返回E3.否则扫描至算式末尾
E5.判断Current==Start,如果不相等,标记Current,找到Current在算式最开始出现的地方.返回E3.
E6.输出右括号,返回E2
证明
针对每一个未标记的元素根据算式遍历找到最终的替换元素,然后标记该元素,显然可以找出所有元素最终替换元素,复杂度为O(N*L)
代码实现
void ChangeStr(char *str) { int i; char pre; for(i=0;str[i]!='