【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
来源:互联网 发布:网络机顶盒连接电视 编辑:程序博客网 时间:2024/05/16 08:55
【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
GCD算法:(辗转相除法/欧几里得算法)
gcd是求最大公约数的算法,作为TAOCP第一个算法
gcd算法流程:
首先给定两个整数m,n(m大于等于n)如果小于则直接交换再处理
①求余数 r=m%n
②假如r=0,算法结束,n即为所求
否则,重新令m <- n, n <-r 之后循环
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
STL中rotate算法:
对于数组移位问题,可以采用下面方法:
①动态分配一个同样长的数组,将数据复制到该数组并改变次序,再复制回原数组
②利用三次反转交换,首先对序列先部分逆序,之后再对后半部分逆序,之后对整个序列全部逆序。ba = (br)^T(ar)^T = (arbr)^T
③分组交换—及可能是数组的前面连续几个数为所要的结果
举例:如果a长度小于b,将ab分成a0a1b,交换a0和b,得到ba1a0,只需要再交换a1和a0;如果a长度小于b,将ab分成ab0b1,交换a和b0,得到b0ab1,只需要交换a和b0
我们考虑,上面这组分组交换的思想,和我们gcd算法很相似。
④所有序号为(j+i*m)%n(j表示每个循环链起始位置,i为计数变量,m表示左旋转位数,n表示字符串的长度)这样就会构成一个循环链(gcd(n,m)个),每个循环链上的元素只要移动一个位置,即可让整个过程交换了n次。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
左旋转字符串
讨论:
1)如果m,n互为质数的情况,(公约数只有1的数叫作为质数)
for i = 0:n-1 k = i * m % n;end
举例:m=3,n=4 abcd -> dabc
ch[0]->temp,ch[3]->ch[0],ch[2]=ch[3],ch[1][2],temp->ch[1]
k寻列为0,3,2,1 发现这个就是上面依次赋值的序列。
2)如果m,n不是互为质数时,我们要把它分成一个个互不影响的循环环所有序号为(j + i * m) % n(j 为0 到gcd(n, m)-1 之间的某一整数,i = 0:n-1)会构成一个循环链,一共有gcd(n, m)个循环链,对每个循环链分别进行一次内循环就行了。
void rotate(string &str, int m){ int lenOfStr = str.length(); int numOfGroup = gcd(lenOfStr, m); //求最大公约数 int elemInSub = lenOfStr/numOfGroup; //外循环次数j为循环链的个数 for(int j = 0;j < numOfGroup; j++) { char tmp = str[j]; for(int i = 0; i < elemInsub - 1; i++) //内循环次数i为每个循环链上的元素的个数,n/gcd(m,n)次; str[(j+i*m)%lenOfStr] = str[(j+(i+1)*m)%lenOfStr]; str[(j+i*m)%lenofStr] = temp; }}//改写void my_rotate(char *begin, char *mid, char *end){ int n = end - begin; int k = mid - begin; int d = gcd(n,k); int i,j; for(i = 0; i < d; i++) { int temp = begin[i]; int last = i; //i+k为i右移k的位置,%n是当i+k>n时,从左重新开始 for(j = (i+k)%n; j != i; j = (j+k)%n) { begin[last] = begin[j]; last = j; } begin[last] = temp; }}
举例:
1.好比5 个学生,,编号从0 开始,即0 1 2 3 4,老师说报数,规则是从第一个学生开始,中间隔一个学生报数。报数的学生编号肯定是0 2 4 1 3。这里就相当于i 为0,k 为2,n 为5;2.然后老师又说,编号为0 的学生出列,其他学生到在他前一个报数的学生位置上去,那么学生从0 1 2 3 4=》2 3 4 _ 1,最后老师说,编号0 到剩余空位去,得到最终排位2 3 4 0 1。此时的结果,实际上就是相当于上述程序中左移k=2 个位置了。而至于为什么让编号为0 的学生出列。实际是这句:int last = i; 因为要达到这样的效果0 1 2 3 4 => 2 3 4
0 1,那么2 3 4 必须要移到前面去。
这里还需要进一步理解。
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
三步翻转法:
反转X^T X=“abc” X^T="cba" (X^TY^T)^T = YX
参考代码:
//三步翻转法.cppchar * invert(char *start, char *end){ char tmp, *ptmp = start; while(start != NULL && end != NULL && start < end) { tmp = *start; *start = *end; *end = tmp; start++; end--; } return ptmp;}char *left(char *s, int pos)//pos是要旋转的字符个数{ int len = strlen(s); invert(s,s+(pos-1)); //abc -> cba invert(s+pos,s+(len-1)); //def -> fed invert(s,s+(len - 1)); //cbafed -> defabc return s;}
- 【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
- 【程序员编程艺术】学习记录1:左旋转字符串之指针翻转法
- 程序员编程艺术:第一章、左旋转字符串
- 【程序员编程艺术】字符串左旋转
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术:第一章、左旋转字符串
- 程序员编程艺术:第一章、左旋转字符串
- 程序员编程艺术1:左旋转字符串
- 程序员编程艺术----1、左旋转字符串
- 【程序员编程艺术】第一章:左旋转字符串
- 左旋转字符串(数组循环移位)
- 数组循环移位(左旋转字符串)
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术(算法卷):第一章、左旋转字符串
- 程序员编程艺术_第一章左旋转字符串_C实现
- 《程序员编程艺术》笔记—左旋转字符串
- 2进制 8进制 10进制 16进制 数值表示之一般规律
- Web.config配置文件详解
- UVA 11427 - Expect the Expected(概率递推期望)
- 使用View.getWidth()方法出现的问题及解决方法
- Linux磁盘挂载操作手册
- 【程序员编程艺术】学习记录2:左旋转字符串之循环移位法
- 【转】在sublime text2中直接编译java文件
- poj-1273
- Anton and Letters - CF#253 (Div. 2)A (443A) 大水
- LCD驱动调试常见问题总结
- Python学习笔记(二):循环
- The resource is not on the build path of a java project
- HTML中的表单
- Kolya and Tandem Repeat - CF#253 (Div. 2)B (443B) 哈希或水题