-
问题描述
对于给定的正整数n,格雷码为满足如下条件的一个编码序列:
(1) 序列由2n个编码组成,每个编码都是长度为n的二进制位串。
(2) 序列中无相同的编码。
(3) 序列中位置相邻的两个编码恰有一位不同。
例如:n=4时的格雷码为:
0 0 0 0
0 0 0 1
0 0 1 1
0 0 1 0
0 1 1 0
0 1 1 1
0 1 0 1
0 1 0 0
1 1 0 0
1 1 0 1
1 1 1 1
1 1 1 0
1 0 1 0
1 0 1 1
1 0 0 1
1 0 0 0
设计求格雷码的递归算法并实现。 -
实现思路:
文件里先放0000,0001. 每次都倒序读取文件内内容,并修改高一位为1,如:0001->0011,0010->0110. 随后顺序写入文件. -
源代码:
-
获取文件夹字符串
public void getStrBuilder(int offset) throws IOException { RandomAccessFile rf = null; int n=LENTH; rf = new RandomAccessFile(FILEPATH, "r"); long len = rf.length(); long start = rf.getFilePointer();//开始位置 long cursor = start + len - 1;//结尾位置 rf.seek(cursor); /*cursor设为最后一句的开始位置*/ if(rf.read()==‘\\n‘) { cursor-=n; } else { cursor-=n-1; } int from=offset; int to = from +1; while (cursor >= 0) { rf.seek(cursor); cursor-=n+1;//每句开头 line=rf.readLine(); sBuilder.append(line).append(‘\\n‘); sBuilder.replace(from, to, "1");//修改from处 为 1 from += n+1; to =from+1; } }
函数用法:
seek(cursor):移动文件指针,从0开始
readline():读取整行,从当前指针开始,直到碰到
\\n
,返回值:字符串(不含\\n
)
replace(from, to, string):替代从from到to前一位的字符串为string.如:replace(1,3,”111”):”0000”->”01110” -
递归加上1
public void grayCode(int offset) throws IOException { getStrBuilder(offset);//反向读取文件后的StringBuilder FileWriter fileWriter = new FileWriter(FILEPATH,true); fileWriter.write(sBuilder.toString()); //flush()仅仅是刷新缓冲区(一般写字符时要用,因为字符是先进入的缓冲区),流对象还可以继续使用 fileWriter.flush(); //sBuilder清空 sBuilder.delete(0, sBuilder.length()); offset--; if(offset>=0) { grayCode(offset); } }
-
函数用法:
delete(1,2): 如:”12345”->”1345”
flush()仅仅是刷新缓冲区(一般写字符时要用,因为字符是先进入的缓冲区),流对象还可以继续使用
close()关闭流对象,但是先刷新一次缓冲区,关闭之后,流对象不可以继续再使用了。
4. 完整代码:https://github.com/waddless/courses/tree/master/%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90/GrayCode