编程珠玑(二)字符串左旋

来源:互联网 发布:如何查看淘宝宝贝排名 编辑:程序博客网 时间:2024/05/17 07:13

编程珠玑第二章的内容,有些内容没有看明白作者的意思。下面是向量左旋和变位词的问题。

一、将一个n元向量左旋转i个位置。例如当N=8,i=3时,向量abcdefgh旋转为defghabc。
这个题目编程之美也有2.17节数组的循环移位和3.1节字符串移位包含的问题。总结下,大概有5种解法,但是编程珠玑上有两种不是很明白,简单介绍下三种算法。

第一种算法比较直接,可以写一个每次都向左移动一位,移动3次即可完成,算法复杂度为i*N。这里还有一个误区,往往会认为i<N其实,并不一定,也可能会有i>>N的情况,这个时候,可以注意到当循环移动N次后向量还原成原来的样子,所以可以先对i=i%N,这样的话i就不会很大,算法复杂度为O(N2)。

第二种算法可以利用空间换时间的方法。也是先对i处理i=i%N,然后开辟一个i大小的空间,保存字符串前i个值。然后直接对把字符串从第i位向前移动i位,然后把空间i个字符补充在后面即可。

第三种算法是通过反转,可以把字符串分为ab两个字串,对a反转~a,对b反转得到~b,ab变为~a~b然后对~a~b整体反转,即可得到ba。此算法还可以针对有些要求,例如要求对abc字符串中c串和a串调换位置,即可对a、b、c串分别进行反转然后整体反转即可。这样时间复杂度只与N有关系为O(N)。下面是三种算法的代码。

#include <iostream>using namespace std;void leftShift1(char *a, int len, int i);void leftShift2(char *a, int len, int i);void leftShift3(char *a, int len, int i);void reverse(char *a, int s, int e);int main(){        char a[] = "abcdefgh";        leftShift3(a, 8, 3);        printf("%s\n", a);        return 0;}void leftShift1(char *a, int len, int i){        i=i%len;        while(i--)        {                char temp = a[0];                for(int j=0; j<len; j++)                        a[j] = a[j+1];                a[len-1] = temp;        }}void leftShift2(char *a, int len, int i){        char *temp = new char[i]();        memcpy(temp, a, i);        memcpy(a, &a[i], len-i);        memcpy(&a[len-i], temp, i);}void leftShift3(char *a, int len, int i){        reverse(a, 0, i-1);        reverse(a, i, len-1);        reverse(a, 0, len-1);}void reverse(char *a, int s, int e){        while(s<e)        {                char temp = a[s];                a[s] = a[e];                a[e] = temp;                s++;                e--;        }}


 

原创粉丝点击