编程珠玑2章B问题--n元一维向量向左旋转i个位置
来源:互联网 发布:查找客户资料的软件 编辑:程序博客网 时间:2024/05/14 10:37
问题:将一个n元一维向量向左旋转i个位置,要求使用一个n元的中间向量在n步内完成该工作,仅使用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转。
思路:
想法1:移动x[0]到临时变量t,然后移动x[i]至x[0],x[2i]至x[i],以此类推(将x中的所有下标对n取模),直至返回到取x[0]中的元素,此时改为从t取值然后终止过程。以此类推,直至把x[0]至x[i-1]个变量移动。
想法2:问题可以理解为将数组ab转换成ba。从ab开始,首先对a求逆,得到a'b,然后对b求逆,得到a'b',最后整体求逆,得到(b'a')',就是ba。
代码:
想法1
#include <stdio.h>#define MAXSIZE 10void print(const int num[]);void move(int num[],int move_num);int gcd(int num,int move_num);/* 打印信息*/void print(const int num[]){ int tmp_index = 0; printf("(num) : "); while(tmp_index<MAXSIZE) { printf("%d ", num[tmp_index]); tmp_index++; } printf("\n");}/* 向左移动*/void move(int num[],int move_num){ int index = 0;//遍历次数的索引 int times = gcd(MAXSIZE,move_num);//MAXSIZE和move_num的最大公约数,即遍历次数 int tmp_value = 0;//存储当前遍历的第一个值的临时变量,表示t int tmp_index = 0;//向后移动move_num位的临时变量,表示x[i]中的i int tmp_index_index = 0;//向后移动k*move_num位的临时变量(k>=1),表示x[i*2]中的i*2 for(index = 0;index< times;index++)//共遍历times次 { tmp_value = num[index]; tmp_index = index; while(1) { tmp_index_index = tmp_index + move_num; if(tmp_index_index >= MAXSIZE)//超过最大值,则减去最大值,剩余值表示新的位置 tmp_index_index -= MAXSIZE; if(tmp_index_index == index)//与当前索引值相同,说明当前一次的遍历结束(否则,就会重复遍历相同位置),再次遍历下一个 break; num[tmp_index] = num[tmp_index_index];//把x[2*i]的位置移动到x[i]上 tmp_index = tmp_index_index;//探针移动到i*2上 } num[tmp_index] = tmp_value;//把t值赋予相应的位置 print(num);//打印每次遍历后的数组 }}/* 求最大公约数*/int gcd(int num,int move_num){ return (!move_num)?num:gcd(move_num,num%move_num);}/* 主程序*/int main(){ int num[MAXSIZE] = {0,1,2,3,4,5,6,7,8,9}; int move_num = 0; char c; print(num); //输入向左移动次数(大于0) printf("Input times for moving left: "); while(scanf("%d",&move_num) != 1 || move_num <= 0 || move_num >= MAXSIZE) { printf("please input times (>0 and <MAXSIZE)!\n"); while((c = getchar()) != '\n' && c != EOF); printf("Input times for moving left: "); } //移动move_num move(num,move_num); return 0;}
想法1的时间复杂度为O(n),空间复杂度为O(n)
想法2
#include <stdio.h>#define MAXSIZE 10void print(const int num[]);void move(int num[],int move_num);void reverse(int num[],int start_pos,int end_pos);/* 打印信息*/void print(const int num[]){ int tmp_index = 0; printf("(num) : "); while(tmp_index<MAXSIZE) { printf("%d ", num[tmp_index]); tmp_index++; } printf("\n");}/* 向左移动*/void move(int num[],int move_num){ reverse(num,0,move_num-1);//翻转a,得到a' reverse(num,move_num,MAXSIZE-1);//翻转b,得到b' reverse(num,0,MAXSIZE-1);//翻转a'b'}/* 翻转 * @param * num[]:数组 * start_pos:起始位置 * end_pos:终止位置 */void reverse(int num[],int start_pos,int end_pos){ int tmp_value = 0; for(;start_pos<end_pos;start_pos++,end_pos--) { tmp_value = num[start_pos]; num[start_pos] = num[end_pos]; num[end_pos] = tmp_value; } print(num);}/* 主程序 * 问题:将一个n元一维向量向左旋转i个位置,要求使用一个n元的中间向量在n步内完成该工作, * 仅使用数十个额外字节的存储空间,在正比于n的时间内完成向量的旋转。 * 思路:问题可以理解为将数组ab转换成ba。从ab开始,首先对a求逆,得到a'b,然后对b求逆,得到a'b',最后整体求逆,得到(b'a')',就是ba。 */int main(){ int num[MAXSIZE] = {0,1,2,3,4,5,6,7,8,9}; int move_num = 0; char c; print(num); //输入向左移动次数(大于0) printf("Input times for moving left: "); while(scanf("%d",&move_num) != 1 || move_num <= 0 || move_num >= MAXSIZE) { printf("please input times (>0 and <MAXSIZE)!\n"); while((c = getchar()) != '\n' && c != EOF); printf("Input times for moving left: "); } //移动move_num move(num,move_num); return 0;}
想法2的时间复杂度为O(n),空间复杂度为O(n)
- 编程珠玑2章B问题--n元一维向量向左旋转i个位置
- 《编程珠玑(第2版)》笔记——将一个n元一维向量向左旋转i个位置(第2章)
- 《编程珠玑(第2版)》笔记——将一个n元一维向量向左旋转i个位置(第2章)
- 《编程珠玑(第2版)》笔记——将一个n元一维向量向左旋转i个位置(第2章)
- 《编程珠玑(第2版)》笔记——将一个n元一维向量向左旋转i个位置(第2章)
- n元一维向量向左旋转i个位置
- 编程珠玑---第二章---n元一维向量向左旋转
- 编程珠玑(1):将一个n元一维向量向左旋转i个位置。例如当n=8且i=3时,向量abcdefgh 旋转为defghabc
- 《编程珠玑》2.3 将一个n元一维向量左旋转i个位置
- n元一维向量旋转问题(编程珠玑--第2章--问题B )
- 编程珠玑:n元一维向量左旋移i个位置
- 问题:将一个n元一维向量向左旋转i个位置,例如,当n=8且i=3时,向量abcdefgh旋转为defghabc。
- 【编程珠玑】将一个n元向量左旋转i个位置
- 编程珠玑第二章问题B: n元一维向量旋转问题之java实现
- 将一个n元一维向量向左旋转i个位置。例如,当n = 8且i = 3时,向量abcdefgh旋转为defghabc
- 平移向量:将一个具有n个元素的一维向量向左旋转i个位置
- 编程珠玑之第二章questionB: n元一维向量旋转问题
- 关于n个元素的向量x向左移动位得问题(原问题来自于编程珠玑)
- JSP中读文件和写文件的例子
- linux内核模块编程----ubuntu下我的第一个Hello World驱动
- 26. 不要忽视错误!
- 常见算法-多项式计算(1)
- request.getRemoteAddr()获取的值为0:0:0:0:0:0:0:1?
- 编程珠玑2章B问题--n元一维向量向左旋转i个位置
- php curl 对IP与来源地址的伪造
- 跟我一起写 Makefile(一)
- GDK事件与GTK signal的前世今生
- 用JDOM包实现生成XML文件的简单示例
- 考拉兹猜想
- LibLinear(SVM包)使用说明之(一)README
- Linux 各个文件夹的作用
- 写给自己