典型的向量旋转问题
2014-09-09 21:57
246 查看
问题:
《编程珠玑》里面典型的向量旋转问题。
分析:
直接转载的,认为写的比较好
--------------------------------------------------------
问题描述如下:Rotate vector x
left by d positions. 把x
向左旋转d个位置。
例如:当n=8, d=3, 把abcdefgh向左旋转3位成defghabc.
首先d=d%n:
解法一:Pricey Solutions 时间复杂度和空间复杂度均为0(n)
用O(d)的临时空间存储x[1-d], 把剩余元素向左移动, 然后再把临时空间移到x后面去。
时间复杂度:O(n); 空间复杂度为 O(d) = O(n);
解法二:A Juggling Algorithm
移动x[0]到temp, 移动x[d]到x[0]的位置, 移动x[2d]到x[d]的位置,x[(k+1)d%n]移动到x[kd%n]的位置,如下图所示。
解法三:Block-swap Algorithm
旋转向量x其实就是交换向量ab的二段得到ba,其中a代表x的前d个元素。例如abcdefgh向左旋转3位成defghabc,即交换(abc)和(defgh).
假设a比b短,则可以将b分为二段[bl]和[br]其中[br]长度和a相同。交换ab即为交换a[bl][br],则可首先交换a和[br]得到[br][bl]a,a已经处于正确位置,接下来可递归需交换[br][bl],从而得[bl][br]a即ba。
解法四:The Reversal Algorithm
从解法三看到交换ab,其实可以先翻转a得到a'然后翻转b得到b‘,最后将a'b'整体翻转ba。
例如:abcdefgh=>[cba][hgfed]=>[defghabc]
代码如下:
出处:http://wansishuang.appspot.com/?p=77001
---------------------------------------------------------
第二种方法时,用到了gcd,循环次数是n和d的最大公约数,如果n和d最大公约数是1,那么循环只要执行一次就能将所有的字符移动到指定位置,这里还是非常巧妙的。
《编程珠玑》里面典型的向量旋转问题。
分析:
直接转载的,认为写的比较好
--------------------------------------------------------
问题描述如下:Rotate vector x
left by d positions. 把x
向左旋转d个位置。
例如:当n=8, d=3, 把abcdefgh向左旋转3位成defghabc.
首先d=d%n:
解法一:Pricey Solutions 时间复杂度和空间复杂度均为0(n)
用O(d)的临时空间存储x[1-d], 把剩余元素向左移动, 然后再把临时空间移到x后面去。
时间复杂度:O(n); 空间复杂度为 O(d) = O(n);
解法二:A Juggling Algorithm
移动x[0]到temp, 移动x[d]到x[0]的位置, 移动x[2d]到x[d]的位置,x[(k+1)d%n]移动到x[kd%n]的位置,如下图所示。
解法三:Block-swap Algorithm
旋转向量x其实就是交换向量ab的二段得到ba,其中a代表x的前d个元素。例如abcdefgh向左旋转3位成defghabc,即交换(abc)和(defgh).
假设a比b短,则可以将b分为二段[bl]和[br]其中[br]长度和a相同。交换ab即为交换a[bl][br],则可首先交换a和[br]得到[br][bl]a,a已经处于正确位置,接下来可递归需交换[br][bl],从而得[bl][br]a即ba。
解法四:The Reversal Algorithm
从解法三看到交换ab,其实可以先翻转a得到a'然后翻转b得到b‘,最后将a'b'整体翻转ba。
例如:abcdefgh=>[cba][hgfed]=>[defghabc]
代码如下:
</** * * Rotate vector x left by d positions * **/ #include <stdio.h> /** * Algorithm 1: pricey algorithm * O(n) time and O(n) extra space **/ void pricey(int x[], int n, int d) { d = d % n; int * temp = new int[d]; for(int i = 0; i < d; i++) //move the first d elements into the temp { temp[i] = x[i]; } for(int i = d; i < n; i++) //move the last n-d elements into the first n-d places { x[i-d] = x[i]; } for(int i = 0 ; i < d; i++) //move the temp into the last d elements { x[n-1-i] = temp[d-1-i]; } delete[] temp; } /** * Algorithm 2: A juggling algorithm * O(n) time and O(1) extra space **/ void swap(int * a, int *b) { int temp = *a; *a = *b; *b = temp; } int gcd(int n, int d) { if(n < d) swap(&n, &d); if(n % d == 0) return d; else return gcd(d, n/d); } void juggling(int x[], int n, int d) { int temp; //store the x[i] int j; for(int i = 0; i < gcd(n, d); i++) { temp = x[i]; j = i; while(1) { int k = (j + d)%n; if( k == i) break; x[j] = x[k]; j = k; } x[j] = temp; } } /** *Algorithm 3: The Block-Swap Algorithm *The idea: change ab to ba *If a is shorter, divide b into bl and br *Swap a and br to change a[bl][br] into [br][bl]a *Then recusive to change [br][bl] * O(n) time and O(1) extra space **/ //swap x[a,a+len-1]and x[b,b+len-1] void swap_block(int x[], int a, int b, int len) { for(int i = 0; i < len; i++) { swap(x+a+i,x+b+i); } } void blockswap(int x[], int n, int d) { d = d % n; if( n ==d || d == 0 ) return; else { int a = 0; int b = d; int a_len = d; int b_len = n - d; while(1) { if( a_len > b_len) { swap_block(x, a, b, b_len); a = a + b_len; a_len = a_len - b_len; } else if( a_len < b_len) { swap_block(x, a, b + b_len - a_len, a_len); b_len = b_len - a_len; } else { swap_block(x, a, b + b_len - a_len, a_len); break; } } } } /** *Algorithm 4: The Reversal Algorithm *The Idea *Reverse a to get a rb. *Reverse b to get a rb r . *Reverse all to get (a rb r ) r = ba. *O(n) time and O(1) extra space **/ void reverse(int x[], int start, int end) { for(int i = start, j = end; i < j; i++, j--) { swap(x+i, x+j); } } void reversal(int x[], int n, int d) { reverse(x, 0, d-1); reverse(x, d, n-1); reverse(x, 0, n-1); } int main() { int x[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; int n = 8; int d = 3; reversal(x, n, d); for(int i = 0; i < n; i++) { printf("%c " , x[i]); } printf("\n"); return 0; }
出处:http://wansishuang.appspot.com/?p=77001
---------------------------------------------------------
第二种方法时,用到了gcd,循环次数是n和d的最大公约数,如果n和d最大公约数是1,那么循环只要执行一次就能将所有的字符移动到指定位置,这里还是非常巧妙的。
相关文章推荐
- 求助,向量旋转问题
- 向量旋转问题
- 《编程珠玑》问题的C实现——2:向量旋转
- 编程珠玑2章B问题--n元一维向量向左旋转i个位置
- n元一维向量旋转问题
- 问题:将一个n元一维向量向左旋转i个位置,例如,当n=8且i=3时,向量abcdefgh旋转为defghabc。
- n 元一维向量旋转问题(编程珠机) 第二章问题B
- 编程珠玑之第二章questionB: n元一维向量旋转问题
- n元一维向量旋转问题(编程珠玑--第2章--问题B )
- {Programming Pearls}第二章--向量旋转问题
- 三角形外接圆的圆心,向量旋转问题,求点(x1,y1)绕点(0,0)旋转a后坐标
- 编程珠玑第二章问题B: n元一维向量旋转问题之java实现
- 向量的旋转
- 绕轴旋转问题
- 探讨:向量(方向)之间的插值-四元数法VS.旋转矩阵法的性能比较
- MFC中OpenGL旋转的问题
- div+css - 其他HTML问题 - Vector Markup Language (VML): - 向量标记语言
- 学习Win CE(使用EVC4开发)碰到的几个典型问题
- [转载]TCP的网络编程中一些典型的问题,以及一些分析和解决方案
- 初装ORACLE 10G后EM登陆的典型问题