使用递归的格雷码

时间:2016-01-12 14:51:11

标签: java

我正在使用格雷码,我几乎得到了所有东西,但是当代码运行时,如1位或2位,它只打印出0000而不是00 01 11 10.

class GrayCode {

     static void genGC(int n){
          if(n == 0){
               System.out.println(n);
          }
          else{
               genGC(n-1);
               genGC(n-1);
          }
     }

     public static void main(String[] args) {
          int a = 2;
          genGC(a);
     }
}

3 个答案:

答案 0 :(得分:0)

你的问题是所需位长的格雷码不仅仅是比特长度格雷码的串联。 It's more complicated than that

这似乎有效 - 尽管有不必要的列表复制量 - 我可能会尝试在以后的版本中修复它。

/**
 * Prefix every element of the list with the string.
 *
 * @param list - The list to prefix.
 * @param prefix - The string to prefix each element.
 * @return - A new prefixed list.
 */
private List<String> prefix(List<String> list, String prefix) {
    List<String> prefixed = new ArrayList<>(list.size());
    for (String s : list) {
        prefixed.add(prefix + s);
    }
    return prefixed;
}

/**
 * Reflect(reverse) a list.
 *
 * @param list - The list to reverse.
 * @return The reversed list.
 */
private List<String> reflected(List<String> list) {
    List<String> reflected = new ArrayList<>(list.size());
    // use an ArrayList so I can reverse iterate.
    for (ListIterator<String> backwards = new ArrayList<>(list).listIterator(list.size()); backwards.hasPrevious();) {
        reflected.add(backwards.previous());

    }
    return reflected;
}

// Grey codes of one-bit numbers is (0,1).
private static final List<String> OneBit = Arrays.asList("0", "1");

public List<String> greyCodes(int bits) {
    if (bits <= 1) {
        return OneBit;
    } else {
        List<String> smaller = greyCodes(bits - 1);
        // Prefix the current list with "0"
        List<String> grey = prefix(smaller, "0");
        // and a reflected version of that list with "1"
        grey.addAll(prefix(reflected(smaller), "1"));
        return grey;
    }
}

答案 1 :(得分:0)

生成具有n位的k th 格雷码的实际递归是(&#39; ||&#39;表示连接):

  1. G(n,k)= 1 ||对于k≥2 n - 1 ,G(n - 1,2 n - k - 1)
  2. G(n,k)= 0 ||对于k n - 1,G(n - 1,k)

使用停止条件G(1,0)= 0且G(1,1)= 1且0≤k≤2 k - 1

注意(2)中的减法。它对应于最后4位数的序列的前半部分是后半部分的镜像的事实。这就是为什么格雷码有时被称为反射二进制码(RBC)。

如果是Lisp / Scheme /等。是你的事,你可以使用:

生成格雷码的位数组
(defun gray (n k)
"Returns the kth Gray code of an n-bit sequence. Output is in the form of a bit array."
  (assert (< k (expt 2 n)) (n) "k cannot be higher than ~A~%" (1- (expt 2 n)))
  (cond
    ((= n 1)
      (if (zerop k) #*0 #*1))
    ((>= k (expt 2 (1- n)))
      (concatenate 'bit-vector #*1 (gray (1- n) (- (expt 2 n) k 1))))
    (t
      (concatenate 'bit-vector #*0 (gray (1- n) k)))))

NB。上面的cond与Java中的switch/case类似。上面的函数是上面递归公式的直接实现。

如果Lisp不是你的事情,如果递归不是你的程序的绝对要求,你可以通过实现公式来修改你的代码:

gray = num ^ (num >> 1)

干杯,  圣保罗

答案 2 :(得分:0)

这是一个相当简单的Java递归程序,它采用正整数n并产生n位格雷码:

public static String swap(String s, String r, int i)
{
    i = i-1;
    String t = s.substring(0,i) + r + s.substring(i+1);
    return t;
}

swap接受一个字符串,然后将其i-1字符更改为另一个仅包含一个字符的字符串。

public static void beckett(int n, String s)
{
    if (n == 0) return;
    beckett(n-1, s);
    System.out.println(swap(s, "1", n)); s = swap(s, "1", n);
    beckett(n-1, s);
}

beckett(参考贝克特的一部名为《 Quad》的剧本)产生格雷码。

public static void grayCodes(int n)
{
    String s = "";
    for (int i = 0; i < n; i++)
        s += "0";
    System.out.println(s);      
    beckett(n, s);
}

grayCodes使beckett的使用更加容易(仅减少了输入数量)。

您可以使用以下方法测试以上方法:

public static void main(String[] args)
{
    int n = Integer.parseInt(args[0]);
    grayCodes(n);
}

对于示例输入3,它提供以下输出:

000
100
010
110
001
101
011
111

希望这会有所帮助。