将一个具有n个元素的一维向量向左旋转i个位置.假若n = 8, i = 3, 那么向量abcdefgh 旋转后为defghabc.
(文中代码部分,均为我用c语言实习.编译器为vc6.若出现错误或者有更好的方法请,请留言交流.谢谢~)
1、将待旋转的向量看作是ab两段,假设a比b短,将b分割为b1和b2使b2长度与a相等.
交换a、b2,这样ab1b2变为b2b1a这样a已经在自己最终的位置上了.下面的工作就变成了旋转b2b1.
/**********************************
Fction:将字符串按条件转置
char * p:字符串首地址
int t:所要选择部分的长度
int n:串的总长度
Return:void
**********************************/
void Q(char *p,int t,int n){
char tmp;
int i;
int flag = 0; //标记变量
char *p1 ; //用于指向b2的头地址
if(n !=1 && n != 0)
{
/*********************************************
判断t即所要旋转的长度是否大于另一部分,因为我们
选择短的那部分,相应的分解长的那部分.所以若t>n-t
则把短的那部分赋值给t
*********************************************/
if(t>n-t){
t = n-t;
flag = 1;
}
//对b2串头地址的初始化
p1 = p+n-t;
//开始交换变量
for(i = 0;i<t;i++){
tmp = *(p1+i);
*(p1+i) = *(p+i);
*(p+i) = tmp;
}
/*********************************************
根据标志位选择递归
若形参t即为分解部分即ab(这里假设a比b短)
则a已经在最终位置固串首地址不变,t不变,所选择串总长度-t
若是ba,则t为需分解的串的长度.这里为了简化代码
我们还把b1b2a看成ab1b2固上文对t赋值n-t
但a被换置前端亦为最终位置固.总串首地址后移t
而总长度-t,下次所旋转的长度在n-t的基础上再-t
*********************************************/
if(flag)
Q((p+t),n-2*t,n-t);
else
Q(p,t,n-t);
}
额~ 太晚了 今天先睡觉
2、这个算法的思想,是利用了这样一个公式.我们把ar看作是串a的转置
(ar br)r = ba
即先把a转置 再把b转置 再把整个串转置 即得到ba
这个算法的实现是3个算法里面最容易实现的
也是最不容易错的,下面是我C的代码实现
/**********************************
Fction:将字符串按条件转置
char * p:字符串首地址
int t:所要选择部分的长度
int n:串的总长度
Return:void
**********************************/
void Q(char str[],int t,int n){
int i ;
char tmp;
for(i = 0;i < t/2;i++ ){
tmp = str[i];
str[i] = str[t-1-i];
str[t-1-i] = tmp;
}
for(i = 0;i < (n-t)/2;i++ ){
tmp = str[t+i];
str[t+i] = str[n-1-i];
str[n-1-i] = tmp;
}
for(i = 0;i < n/2;i++ ){
tmp = str[i];
str[i] = str[n-1-i];
str[n-1-i] = tmp;
}
}
3、这个算法被JonBentley称为杂耍.我觉得也是~不过我不是很喜欢(但JonBentley好像很推崇),
可能是我实现的不好.十分不给力.循环过多了吧.
思想就是 先开辟出来一个字的内存(这也是这个算法的优点,
至始至终就只用了这么一块内存)把要移动的第一块移动到这个内存中
然后把后续的 陆续往前移
例如:a、b、c、d、e、f
我们想把ab移到最后
先a移到那块内存中,然后c→a、e→f、那块内存的a再移到e
如果没完成那么再继续这样移动
/**********************************
Fction:求2个数的最大公约数
int m:操作数
int n:操作数
Return:最大公约数
**********************************/
int gcd(int m,int n){
while(n != m){
if(m > n)
m -= n;
if(m < n)
n -= m;
}
return n;
}
/**********************************
Fction:将字符串按条件转置
char * p:字符串首地址
int t:所要选择部分的长度
int n:串的总长度
Return:void
**********************************/
void Q(char str[],int t,int n){
int i , j , m;
int m = gcd(t,n);
char tmp;
for(i = 0;i < m;i++)
for(k = t/m;k > 0;k--){
tmp = str[i];
for(j = 0;j < (n/m-1);j++)
str[j*m+i] = str[(j+1)*m+i];
str[j*m+i] = tmp;
}
}