Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何编写产生格雷码的递归函数_Java_Recursion - Fatal编程技术网

Java 如何编写产生格雷码的递归函数

Java 如何编写产生格雷码的递归函数,java,recursion,Java,Recursion,我使用的是格雷码,我得到了几乎所有的东西,但是当代码运行时,比如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)

我使用的是格雷码,我得到了几乎所有的东西,但是当代码运行时,比如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);
     }
}

您的问题是,所需位长的格雷码不仅仅是位长小于1的格雷码的级联

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

/**
 * 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;
    }
}
/**
*在列表的每个元素前面加上字符串。
*
*@param list-要添加前缀的列表。
*@param prefix-为每个元素添加前缀的字符串。
*@return-一个新的前缀列表。
*/
私有列表前缀(列表、字符串前缀){
列表前缀=新的ArrayList(List.size());
用于(字符串s:列表){
前缀。添加(前缀+s);
}
返回前缀;
}
/**
*反映(颠倒)一个列表。
*
*@param list-要反转的列表。
*@返回反向列表。
*/
反映的私人列表(列表){
List reflected=newarraylist(List.size());
//使用ArrayList,这样我可以反向迭代。
for(ListIterator向后=新建ArrayList(list).ListIterator(list.size());向后.hasPrevious();){
reflected.add(backwards.previous());
}
回报反映;
}
//一位数字的灰色代码为(0,1)。
私有静态最终列表OneBit=Arrays.asList(“0”、“1”);
公共列表灰色代码(整数位){

如果(位生成具有n位的第k个格雷码的实际递归是(“| |”表示串联):

  • 对于k&geq;2n-1,G(n,k)=1 | G(n-1,2n-k-1)
  • 对于kn-1,G(n,k)=0 | G(n-1,k) 使用停止条件G(1,0)=0和G(1,1)=1,并且具有0&leq;k&leq;2k-1

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

    如果您喜欢Lisp/Scheme/etc,则可以使用以下方法生成带有格雷码的位数组:

    (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)))))
    
    (非灰灰色(n k)
    “返回n位序列的第k个格雷码。输出为位数组形式。”
    (assert(=k(表达式2(1-n)))
    (连接“位向量”#*1(灰色(1-n)((表达式2n)k1)))
    (t
    (连接“位向量#*0(灰色(1-n)k()(#))”))
    
    注意:上面的
    cond
    与Java中的
    switch/case
    类似。上面的函数是上面递归公式的直接实现

    如果您不喜欢Lisp,并且递归不是程序的绝对要求,则可以通过实现以下公式来修改代码:

    gray=num^(num>>1)

    干杯,
    Paulo

    这是一个相当简单的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
    (参考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);
    }
    
    对于示例输入
    3
    ,它给出以下输出:

    000
    100
    010
    110
    001
    101
    011
    111
    

    希望这能有所帮助。

    您只调用
    System.out.println(n);
    如果n为0,您希望得到什么?您到底想要实现什么?
    000
    100
    010
    110
    001
    101
    011
    111