格雷码生成

Posted zhihaowu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了格雷码生成相关的知识,希望对你有一定的参考价值。

  1. 问题描述

    对于给定的正整数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
    设计求格雷码的递归算法并实现。

  2. 实现思路:
    文件里先放0000,0001. 每次都倒序读取文件内内容,并修改高一位为1,如:0001->0011,0010->0110. 随后顺序写入文件.

  3. 源代码:

    1. 获取文件夹字符串

      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”

    2. 递归加上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

?

以上是关于格雷码生成的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 格雷码序列的生成

递归生成格雷码

递归实现生成Grey码

格雷码生成

格雷码的实现

腾讯编程