《编程珠玑》第二章-循环移位
2010-11-08 11:20
295 查看
问题:将一个n维向量向左循环移位m位。如向量0,1,2,3,4,5,6,7,8,9向左循环移位3位,结果是3,4,5,6,7,8,9,0,1,2。
方法1:每次循环移位1位,执行m次。辅助空间1,时间复杂度O(n*m)
方法2:用m维的辅助空间暂存前m个元素,对剩下的n-m个元素进行移位,最后将m个元素移动向量末尾。辅助空间m,时间复杂度O(n)。
方法3:(杂技方法)先a[0]-->temp,然后a[i]-->a[0],a[2i]-->a[i],直到遇到a[0],将temp-->刚才移动的最后一个位置。如
果没有移动完则a[i]-->temp,然后a[1+i]-->a[1],a[1+2i]-->a[1+i],循环,直到全部移动。辅助空间O(1),时间复杂度O(n).
方法4:(求逆方法)利用了
(b,a)=(arbr)r,辅助空间1,时间复杂度O(n). 还可以扩展为(c,b,a)=(ar,br,cr)r噢~
方法5:(分块方法)对于向量(a,b),其中a是m维的,b是n-m维,将b分成两部分,b=(b1,b2),其中b2同a也是m维的,首先交换a和b2的位置。然后对(b2,b1)部分再循环进行上述操作。m>n-m时调换位置,继续。辅助空间O(1),时间复杂度O(n).
效率:分块>求逆>杂技
方法1:每次循环移位1位,执行m次。辅助空间1,时间复杂度O(n*m)
方法2:用m维的辅助空间暂存前m个元素,对剩下的n-m个元素进行移位,最后将m个元素移动向量末尾。辅助空间m,时间复杂度O(n)。
//方法1 int temp; for(int i=0; i<m; i++) { temp = a[0]; for(int j=0; j<n-1; j++) a[j]=a[j+1]; a[n-1] = temp; } //方法2 int t[m]; for(int i=0; i<m; i++) t[i] = a[i]; for(int i=0; i<n-m; i++) a[i] = a[i+m]; for(int i=0; i<m; i++) a[n-m+i] = t[i];
方法3:(杂技方法)先a[0]-->temp,然后a[i]-->a[0],a[2i]-->a[i],直到遇到a[0],将temp-->刚才移动的最后一个位置。如
果没有移动完则a[i]-->temp,然后a[1+i]-->a[1],a[1+2i]-->a[1+i],循环,直到全部移动。辅助空间O(1),时间复杂度O(n).
int count = 0; //count等于n时移动完 int i = 0; int j; int temp; while(1) { temp = a[i]; j = (i+m)%n; while(j != i) { a[(j-m+n)%n] = a[j]; count++; j = (j+m)%n; } a[(i-m+n)%n] = temp; count++; if(count<n) i++; else break; }
方法4:(求逆方法)利用了
(b,a)=(arbr)r,辅助空间1,时间复杂度O(n). 还可以扩展为(c,b,a)=(ar,br,cr)r噢~
void reverse(int *a, int b, int e) { int len = e-b+1; int temp; for(int i=0; i<len/2; i++) { temp = a[b+i]; a[b+i] = a[e-i]; a[e-i] = temp; } } reverse(a,0,m-1); reverse(a,m,n-1); reverse(a,0,n-1);
方法5:(分块方法)对于向量(a,b),其中a是m维的,b是n-m维,将b分成两部分,b=(b1,b2),其中b2同a也是m维的,首先交换a和b2的位置。然后对(b2,b1)部分再循环进行上述操作。m>n-m时调换位置,继续。辅助空间O(1),时间复杂度O(n).
int p = m; int i = m; //每次交换的块元素个数 int j = n-m; //每次交换的两个块的间隔 while(i != j) { if(i>j) //此时i和j的地位就要对调了 { swap(a,p-i,p,j); i -= j; } else { swap(a,p-i,p-i+j,i); j -= i; } } swap(a,p-i,p,i); //swap函数将位p开始和位q开始的m个元素位置对调 void swap(int *a, int p, int q, int len) { int temp; for(int i=0; i<len; i++) { temp = a[p+i]; a[p+i] = a[q+i]; a[q+i] = temp; } }
效率:分块>求逆>杂技
相关文章推荐
- 旋转字符串;编程珠玑第二章;rotate a one-dimensional vector;循环移位数组;编程之美
- 《编程珠玑》第二章-循环移位
- 字符串循环左移——编程珠玑第二章B
- 编程珠机 第二章 字符串循环移位
- 编程之美:第二章 数字之魅 2.17数组循环移位
- 【算法竞赛入门经典学习日记】第二章 循环结构程序设计
- 编程珠玑第二章
- 数组循环移位O(n) AND 按单词反转字符串
- 数组循环移位
- 编程珠玑第二章习题
- 编程珠玑 第二章 习题 2 给定一个包含4300000000个32位证书的顺序文件,求出一个至少包含两次的整数
- 数组循环移位(左旋转字符串)
- F#入门-第二章 F#基础-第八节 for循环
- 循环移位
- 循环移位
- 字符串循环移位
- CMD命令行高级教程精选合编---第二章 DOS循环:for命令详解[转]
- 字符串循环移位
- 如何使用位运算实现循环移位?
- 编程珠玑——字符串移位