第二章 ”啊哈,算法“ P11
问题B:将一个n元一维向量向左旋转i个位置(循环移位),例如abcdefgh左循环移位3个位置变成defghabc
要求:使用一个n元的中间向量在n步内完成,能否仅适用数十个额外字节的存储空间,在正比于n的时间内完成?
"啊哈,灵机一动":
贴个照片,不侵权吧,呵呵,手我加了指甲,分辨手掌正反面
代码:
package org.test.algorithm;
/**
* 翻转算法
* 目标: 把n元一维向量"abcdefg"左旋转3个位置,既字符串循环移位变成"defgabc"
* 约束:时间,仅适用n元的中间向量在n步内完成,在正比于n的时间内完成,空间,仅适用数十个额外字节的存储空间
* @author Administrator
*
*/
public class FingerTranslate {
private static String srcStr = "abcdefg";
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("input: "+srcStr+" 左移位3次后:");
System.out.println("output: "+moveFor(srcStr,3));
}
/**
* 翻转 一个字符数组
* {a,b,c} to {c,b,a}
*
* @param charArr
*/
public static char[] reverseArray(char[] charArr ){
int len = charArr.length;
int changeTimes = len/2;
char charTmp = 0;
for(int i=0;i<changeTimes;i++){
charTmp = charArr[i];
charArr[i] = charArr[len-i-1];
charArr[len-i-1] = charTmp;
}
return charArr;
}
/**
* 把srcStr向左循环移位moveTimes次
* @param _srcStr
* @param moveTimes
* @return
*/
public static String moveFor(String _srcStr,int moveTimes){
int lenInput = _srcStr.length();
/**
* 把整个串截断两部分head(abc) 和tail(defg)
* 步骤:
* 1,翻转head
* 2,翻转tail
* 3,翻转{head,tail}
*/
//构造head 承装abc
char[] arrHead = new char[moveTimes];
arrHead = _srcStr.substring(0, moveTimes).toCharArray();
//构造tail 承装defg
char[] arrTail = new char[lenInput-moveTimes];
arrTail = _srcStr.substring(moveTimes, lenInput).toCharArray();
//构造total承装所有字符(各自翻转后的 head+tail :cba gfed)
char[] arrTotal = new char[lenInput];
//1
reverseArray(arrHead);
//2
reverseArray(arrTail);
//3
/**
* head并入
*/
System.arraycopy(arrHead, 0, arrTotal, 0, arrHead.length);
/**
* tail并入
*/
System.arraycopy(arrTail, 0, arrTotal, moveTimes, arrTail.length);
reverseArray(arrTotal);
return new String(arrTotal);
}
}
package org.test.algorithm;
import junit.framework.TestCase;
public class FingerTranslateTest extends TestCase {
FingerTranslate ft =new FingerTranslate();
String tmp = "abcdefgh";
public void testReverseArray() {
char[] chars = {'a','b','c','d'};
assertEquals("", "dcba", new String(ft.reverseArray(chars)));
}
public void testMoveFor() {
String result = ft.moveFor(tmp, 4);
assertEquals("", "efghabcd", result);
}
}