关于字符串循环左移的若干解决方法

题目描述:对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。

方法一:使用辅助内存

    string LeftRotateString(string str, int n) {
        
        if(str.length()==0) return str;
        n=n%str.length();
    	string Tail(str,0,n);
        string Head(str,n);
         return Head+Tail;
    }
方法二:分段翻转
abc->cba

XYZdef->fedZYX

合并cbafedZYX->XYZdefabc

string LeftRotateString(string str, int n) {
        reverse(str.begin(),str.begin()+n);
        reverse(str.begin()+n,str.end());
        reverse(str.begin(),str.end());
        return str; 
    }
方法三:海豚算法

只借助若干个字节的缓存,在原内存中进行修改,时间复杂度也比较低

int gcd(int x, int y)  
{     
    int z = y;  
    while(x%y!=0)  
    {  
        z = x%y;  
        x = y;  
        y = z;    
    }  
    return z;  
}  
void Shifting(char * pArry, int rotdistance, int len)  
{  
    int i, j;  
    char temp;  
    int igcd = gcd(rotdistance, len);   
    for (i = 0; i < igcd; i++)  
    {  
        temp = pArry[i];  
        j = i;  
        for (; ;)  
        {  
            int k = j + rotdistance;  
            k %= len;  
            if ( k == i)  
            {  
                break;  
            }  
            pArry[j] = pArry[k];  
            j = k;  
        }  
        pArry[j] = temp;  
    }  
}  
原理是利用最大公约数。在上面的例子中,rotdistance=3,igcd=3,len=9;所以进行三次循环每次循环的(j,k)对分别是(0,3,6),(1,4,7)(2,5,8),这样所有的就都遍历一遍了。与第二种方法相比,就排除了rotdistance=0的翻转两次的情况。

方法四:分块交换

 //交换pArry[a...a+m-1]和pArry[b...b+m-1]  
void myswap(char *pArry, int a, int b, int m)  
{  
    char temp;  
    for (int i = 0; i < m; i++)  
    {  
        temp = pArry[a + i];  
        pArry[a + i] = pArry[b + i];  
        pArry[b + i] = temp;  
    }  
  
}  
  
void Shifting(char * pArry, int rotdistance, int len)  
{  
    if (rotdistance == 0 || rotdistance == len)   
    {  
        return;  
    }  
  
    int i, j, p;  
    i = p = rotdistance;  
    j = len - p;  
  
    while (i != j)  
    {  
        if (i > j)  
        {  
            myswap(pArry, p - i, p, j);  
            i -= j;  
        }  
        else  
        {  
            myswap(pArry, p - i, p + j - i, i);  
            j -= i;  
        }  
    }  
    myswap(pArry, p - i, p, i);  
}  
本方法





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值