左旋字符串
2015-07-17 11:57
218 查看
目标:rotate(s,m)
将字符串s的前m位左旋至末尾。
例:s = abcdefghijk
rotate(s,3) = defghijkabc
思路:
1. 假设字符串s需要调整位置,设置指针p1指向s起点,p2指向起点+m的位置,这里p1->a, p2->d。
2. 交换p1和p2指向的元素,同时让p1++, p2++。 这样的动作持续 k = (n-m) - (n%m) 次,其中n为s的长度。
为什么要这么多次呢?上例中,n=11, m =3,则k等于 (11-3) - (11%3) = 6次。经过6次第二步的操作以后s变成了defghi abc jk。式子中11%3的意思是不够m位的部分,11-3的意思是以p2为坐标,到字符串s尾巴距离多少。进入步骤3.
3. 此时s=defghi abc jk,这时我们只需要将jk移动到abc前面即可,而前面的部分defghi不用管。所以这里只关心abcjk这一部分,设为s。此时s的长度为5,移动的目标是jk,长度m=2。p1指向尾巴,p2指向尾巴-m的位置。交换p1和p2指向的元素,同时让p1--, p2--。(例如,第一次就是k与c交换位置,然后p2指向b,p1指向j)。这样的动作持续k=(n-m) - (n%m)次。 (其实这步的操作就完全和步骤2相反)。执行完步骤3后,返回步骤2.
4. 当s的头尾指针指向一个元素,或者m=0的时候,结束递归。
java代码如下。
方法2
对于一个字符串s = ab. a和b是s的子字符串。假设a长度为m,那么目标就是经过了rotate(s,m)操作后,s变成ba。
思路
对于s=ab,有ba = (a'b')'
其中a'等于a的反转,例如a = abc,那么a' = cba
假设s=abcdefg,那么a=abc, b= defg,则rotate(s,m) = (a'b')' = cbagfed=defgabc。
代码
字符串反转部分
这里利用了递归的思想:如果我要反转s,我可以先把s的第一个元素放到最后,然后单独对剩下的s-1个元素进行反转操作。(汉诺塔问题的解决方法)
rotate(s,m)
将字符串s的前m位左旋至末尾。
例:s = abcdefghijk
rotate(s,3) = defghijkabc
思路:
1. 假设字符串s需要调整位置,设置指针p1指向s起点,p2指向起点+m的位置,这里p1->a, p2->d。
2. 交换p1和p2指向的元素,同时让p1++, p2++。 这样的动作持续 k = (n-m) - (n%m) 次,其中n为s的长度。
为什么要这么多次呢?上例中,n=11, m =3,则k等于 (11-3) - (11%3) = 6次。经过6次第二步的操作以后s变成了defghi abc jk。式子中11%3的意思是不够m位的部分,11-3的意思是以p2为坐标,到字符串s尾巴距离多少。进入步骤3.
3. 此时s=defghi abc jk,这时我们只需要将jk移动到abc前面即可,而前面的部分defghi不用管。所以这里只关心abcjk这一部分,设为s。此时s的长度为5,移动的目标是jk,长度m=2。p1指向尾巴,p2指向尾巴-m的位置。交换p1和p2指向的元素,同时让p1--, p2--。(例如,第一次就是k与c交换位置,然后p2指向b,p1指向j)。这样的动作持续k=(n-m) - (n%m)次。 (其实这步的操作就完全和步骤2相反)。执行完步骤3后,返回步骤2.
4. 当s的头尾指针指向一个元素,或者m=0的时候,结束递归。
java代码如下。
private static void rotate(String array, int n, int m, int head, int tail, boolean flag){ int j = 0; if (head == tail || m <= 0) return; //right move if (flag == true){ int p1 = head; int p2 = head + m; int k = (n-m) - (n % m);//移动的次数 for(int i = 0; i< k; i++, p1++, p2++){ array = swap(array,p1,p2); } rotate(array, n-k, n%m, p1, tail, false);//enter the left move } else{ int p1 = tail; int p2 = tail - m; int k = (n-m) - (n%m); for(int i = 0; i<k; i++, p1--, p2--){ array = swap(array,p1,p2); } rotate(array,n-k, n%m, head, p1, true); } }
方法2
对于一个字符串s = ab. a和b是s的子字符串。假设a长度为m,那么目标就是经过了rotate(s,m)操作后,s变成ba。
思路
对于s=ab,有ba = (a'b')'
其中a'等于a的反转,例如a = abc,那么a' = cba
假设s=abcdefg,那么a=abc, b= defg,则rotate(s,m) = (a'b')' = cbagfed=defgabc。
代码
字符串反转部分
public static String reverse(String s){ if(s.length()<=0 || s == null) return s; return reverse(s.substring(1)) + s.charAt(0); }
这里利用了递归的思想:如果我要反转s,我可以先把s的第一个元素放到最后,然后单独对剩下的s-1个元素进行反转操作。(汉诺塔问题的解决方法)
rotate(s,m)
public static String rotate(String s, int m){ String sa = s.substring(0, m); String sb = s.substring(m); return reverse(reverse(sa) + reverse(sb) ); }
相关文章推荐
- Python的Django框架下管理站点的基本方法
- 7. JavaScript HTML DOM - 改变 CSS
- 程序员禅的10条法则
- VMware Workstation unrecoverable error (disk error while paging) has occurred
- ThreadPoolExecutor使用介绍
- HttpClient_4 用法 由HttpClient_3 升级到 HttpClient_4 必看
- freemarker获取map
- Mysql主从配置,实现读写分离
- MQX中如何使用中断?
- vertical-align和line-height的那些事
- 辗转相除法
- 因为链接服务器 "IP" 的 OLE DB 访问接口 "SQLNCLI" 无法启动分布式事务
- php+html5基于websocket实现聊天室的方法
- 数字证书
- FastCgi与PHP-fpm之间是个什么样的关系
- GeoGlobe系列软件使用流程
- 安卓4.4后实现透明状态栏
- AbstractFactory Pattern
- mysql命令集
- JS中call和apply区别有哪些 记录